C#与C++ dll之间传递字符串string wchar_t* char* IntPtr问题
作者:tinghe17
C#与C++ dll之间传递字符串string wchar_t* char* IntPtr问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
C#与C++ dll之间传递字符串string wchar_t* char* IntPtr
1、由C#向C++ dll 传入字符串时,参数直接用string,设置编码格式 CharSet.Unicode CharSet.Ansi。
C++ dll接收使用wchar_t* 或 char*。
2、由C++ dll返回字符串,使用 wchar_t 或char*。
- .net 4.0 C#可以直接使用string接收,很方便。
- .net 4.0+ C# 用 IntPtr 接收,使用string接收调试不行。
dll代码如下:
extern "C" _declspec(dllexport)const wchar_t* Diagnoser(wchar_t* inputText) { delete diagnoser; diagnoser = new FireEye::Diagnoser(); diagnoser->diagnose(inputText); diagnoser->report(); return diagnoser->reportText.c_str(); }
C#代码如下:
//声明 [DllImport("FireEyeDll.dll", CharSet = CharSet.Unicode , CallingConvention = CallingConvention.Cdecl)] //public static extern string Diagnoser(string inputText); //.net 4.0 public static extern IntPtr Diagnoser(string inputText); //调用 //outputBox.Text = Diagnoser(inputBox.Text); //.net 4.0 IntPtr outPtr = Diagnoser(inputBox.Text); outputBox.Text = Marshal.PtrToStringUni(outPtr);
C#调用C++ DLL的步骤以及遇到的乱码等问题
C++ DLL动态库Lib_LR.dll
函数声明:
DLL_API_LR void GetAuthInfo(char* strCode);
函数定义:
两个入参,两个出参
void GetAuthInfo(int inPrama1, char *inParam2, int outParam1, char *outParam2) { char buff[2048]; memset(buff, 0, 2048); std::ifstream inFile("license.lr", std::ios::binary); if (inFile.fail()) { return; } else { inFile.read(buff, sizeof(temp)); inFile.close(); } memcpy(outParam2, buff, outParam2.length()); string strCode=outParam2; outParam1=strCode.length(); }
C#调用流程
函数引用:
[DllImport("Lib_LR.dll", EntryPoint = "GetAuthInfo", CallingConvention = CallingConvention.Cdecl)] public static extern void GetAuthInfo(ref int InParam1, string nInPrama2, StringBuilder strCode);
函数调用:
int inParam1=0; int outParam1=0; string inParam2="测试"; StringBuilder outParam2= new StringBuilder(1024); //注意:调用函数的时候,int型的出口参数要加ref,出口字符串参数要声明StringBuilder类型 GetAuthInfo(inParam1,inParam2,ref outParam1,outParam2);
遇到的问题
1、平台不匹配:
C#工程是基于.net core的webapi项目,默认编译平台选择的是Any CPU,而C++ DLL工程默认的平台是x86,这就产生了调用方(C#工程)和被调用方(DLL)编译平台不匹配的问题。可以尝试通过以下方法来解决:C++ DLL和C#工程编译的时候都选择x86或者x64(前提操作系统是64位才行)。
2、乱码问题:
调用GetAuthInfo函数的时候,获取到的strCode出现乱码,网上给出的解决方法是改变函数参数声明方式public static extern voidGetAuthInfo([MarshalAs(UnmanagedType.LPStr)] StringBuilder strCode)。但是这种方法我试了,没有效果。最后通过修改DLL源码的方式得到解决:在GetAuthInfo函数的最后加上outParam2[strCode.length()] = '\0';这一行代码,也就是在字符串数组末尾添加上结束符。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。