C++ Code:
extern "C" __declspec(dllexport) char* GetStr() { string s = "This is a string"; return _strdup(s.c_str()); //一定要用_strdup()复制一段内存,不然等调用结束字符串内存会被释放得到一串乱码 }
C# Code:
public class CppDll { [DllImport(DllPath, CallingConvention = CallingConvention.Cdecl)] public extern static IntPtr GetStr(); public static GetStrFun() { IntPtr p = GetStr(); //调用DLL函数 string s = Marshal.PtrToStringAnsi(p); //根据实际情况决定使用PtrToStringUni还是PtrToStringAnsi } }
C++ Code:
extern "C" __declspec(dllexport) int GetInt() { return 1; }
C# Code:
public class CppDll { [DllImport(DllPath, CallingConvention = CallingConvention.Cdecl)] public extern static int GetInt(); } int res = CppDll.GetInt(); //调用
除了可以在返回值里带出字符串,也可以在函数参数中带出,类似与C语言中需要获取多个值的情形,这里展示一下DLL中同时传递字符串和整型量。由于C#为托管内存,C++运行在非托管内存,所以需要在C#中手动申请一块内存用来存储C++中返回的值。
C# Code:
public CppDll { [DllImport(DllPath, CallingConvention = CallingConvention.Cdecl)] public extern static int GetCapInfo(int index, IntPtr proName, IntPtr cnt); } IntPtr PproName = Marshal.AllocHGlobal(256); //手动申请存储字符串类型 IntPtr Pcnt = Marshal.AllocHGlobal(sizeof(int)); //存储整数类型 int status = CppDll.GetCapInfo(0, PproName, Pcnt); string proName = Marshal.PtrToStringAnsi(PproName); int cnt = Marshal.ReadInt32(Pcnt); Marshal.FreeHGobal(PproName); //手动申请的内存手动释放 Marshal.FreeHGobal(Pcnt);
C++ Code:
extern "C" __declspec(dllexport) int GetCapInfo(int index, char* proName, int* cnt) //后两个参数为需要传递的值 { if (index >= capHlp.pro_to_cnt.size()) { return -1; } string key = capHlp.proIndex[index]; *cnt = capHlp.pro_to_cnt[key]; // 把需要传递的整数复制到指定内存 sprintf_s(proName, 256, key.c_str()); //把需要传递的字符串复制到指定内存 return 0; }