如何用c#调用c++的dll传递各种稀奇古怪的参数
声明
我知道用c#调用c++是个神烦的事情,在此分享部分传参心得和技巧,不一定是最好的方法,欢迎指正补充。
各种稀奇古怪的参数
1. 传递基础数据 int float double等
extern "C" __declspec(dllexport) int TransData(int a, float b, double c);
int TransData(int a, float b, double c)
{
double sum = a + b + c;
return floor(sum);
}
[DllImport("贫道不是秃驴只是秃.dll", EntryPoint = "TransData", CallingConvention = CallingConvention.Cdecl)]
public static extern int TransData(int a, float b, double c);
2. 传递 string 并接收 string
extern "C" __declspec(dllexport) const char* TransString(const char * inpStr);
const char* TransString(const char* inpStr)
{
std::string recive = inpStr;
std::string demoStr = "我已经收到了:" + recive;
return demoStr.c_str();
}
[DllImport("贫道不是秃驴只是秃.dll", EntryPoint = "TransString", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr TransString(String msg);
IntPtr str_ptr = DllLinker.TransString("我是你papa!");
string result = Marshal.PtrToStringAnsi(str_ptr);
Console.WriteLine(result);
3. 传递数组操作
extern "C" __declspec(dllexport) int TransArr(int * arr, int arrLen);
int TransArr(int* arr, int arrLen)
{
int sum = 0;
for (int i = 0; i < arrLen; i++) {
sum += arr[i];
}
return sum;
}
[DllImport("贫道不是秃驴只是秃.dll", EntryPoint = "TransArr", CallingConvention = CallingConvention.Cdecl)]
public static extern int TransArr(int[] arr, int len);
int[] arr = { 1,2,3,4,5};
int arrSum = DllLinker.TransArr(arr, arr.Length);
Console.WriteLine("数组值的和是:" + arrSum);
3. 传递结构体操作(包含数组,string等)(两种方式)
extern "C" __declspec(dllexport) bool TransStructType1(YourSelf & yourSelf);
extern "C" __declspec(dllexport) void TransStructType2(YourSelf * yourSelf);
bool TransStructType1(YourSelf& yourSelf)
{
yourSelf.age += 5;
yourSelf.childrenId[0] = 1000;
yourSelf.health = HealthType::DEATH;
return true;
}
void TransStructType2(YourSelf* yourSelf)
{
yourSelf->age += 5;
yourSelf->childrenId[0] = 1000;
yourSelf->health = HealthType::DEATH;
}
[DllImport("DLLS/Dll_DataFile.dll", EntryPoint = "TransStructType1", CallingConvention = CallingConvention.Cdecl)]
public static extern bool TransStructType1(ref YourSelf yourSelf);
[DllImport("DLLS/Dll_DataFile.dll", EntryPoint = "TransStructType2", CallingConvention = CallingConvention.Cdecl)]
public static extern void TransStructType2([In, Out] IntPtr yourSelf);
int[] cid= { 1,2,3,4,5,6,7,8,9,0};
YourSelf yourSelf = new YourSelf();
yourSelf.age = 18;
yourSelf.money = 10.8f;
yourSelf.name = "ZhuDaChang";
yourSelf.childrenId = cid;
yourSelf.health = HealthType.OK;
bool res = DllLinker.TransStructType1(ref yourSelf);
Console.WriteLine("反馈bool:" + res + " ref影响yourself的属性age:" + yourSelf.age);
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(YourSelf)));
Marshal.StructureToPtr(yourSelf, ptr, false);
DllLinker.TransStructType2(ptr);
YourSelf effectStruct = (YourSelf)Marshal.PtrToStructure(ptr, typeof(YourSelf));
Console.WriteLine("[in, out]影响yourself的属性age:" + effectStruct.age);
Marshal.FreeHGlobal(ptr);
4. 传递图片操作
这个可以参考我之前的一些博文,连接在下面: c#调用c/c++打包的dll程序实现人脸检测(暨c#和c++之间传递图片解决方案) c#的opencvsharp与c++封装opencv之间的mat对象传递(BitmapData造成图片扭曲的问题记录)
|