c#调用c/c++编写dll
1概述
最近公司需要开发一款编码器的客户端软件,需要在调用到底层DLL.这块问题对我是个全新的知识点,记下来一点体会。
2类型转化
c/C++的数据类型和c#差别很大,作为强类型语言的c#,MS已经帮你规划好一切,涉及不安全的代码,都给你咔嚓掉了或者藏起来了,连数据类型都给你封装起来了。于是乎,各种指针都看不到了,struct传递方式变了,回调函数用委托封装...下面列下运用到的一些类型转化
1 Handle,这家伙到处可见,用intprt代替
2 DWORD,用int代替
3 struct,需要在前面加ref关键字修饰
4 CallBack,强大的回调函数,用委托封装,这个要写个小例子
C++:
typedef void(CALLBACK *MESSAGECALLBACK)
(MESSAGETYPE eMessageType, const STLMessageDataInfo *pstruMsgData, LPVOID lpvUserData1, LPVOID lpvUserData2);
C#:
delegate void CallBack(MESSAGETYPE eMessageType, ref STLMessageDataInfo pstruMsgData, intprt lpvUserData1, intprt lpvUserData2);
5 array,各种大小固定的arry。前面加上一行[MarshalAs(UnmanagedType.ByValArray, SizeConst =count)],其他不变
3遇到的错误
1 传递给系统调用的数据太小
在一个Struct作为参数传递出来的时候,第一次传递正常,第二次传递就出错。
改正方法:标示结构的字符集为Unicode,添加一行[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode)]
2 尝试写入受保护的内存
这个错误很常见,就像那个“未将对象引用设置到对象的应用一样”。最大的可能就是就是c++类型转化为C#类型出错。类型转化5处理不好就出现这个错误。
3 找不到对应的DLL.
这个也很闹心,明明DLL已经放在正确路径,就是弹出来这个很莫名其妙的错误。注意,搞清楚改DLL是否调用了其他DLL的内容,如果有,放入关联的dll,
遇到过两次,都是关联的DLL没放进去,编译的时候最好选x86版本,这样子在64系统也可以用
4总结
第一点:由于DLL一般是别人写的,使用时候一定和对方认真沟通。
第二点:如果文档和demo冲突,建议参考DEMO代码。程序员一般都比较懒,能用代码完成的事一般就不会写文档。。
第三点:仔细仔细再仔细,不要放过每个参数。没有花时间睡觉的人,就要花时间来生病;没花时间检查代码,就要花时间来调试。
代码写完,花点时间看看数据类型有没有正确匹配,有没有少了标点符号,函数签名有没有写错。
浙公网安备 33010602011771号