C#调用C++的dll,传参失败??? - 记一次遇到的问题
前言
C#调用C++的dll已经不是第一次遇到了,然而这一次需要传递复杂结构,果然在过程中遇到了问题。
发现问题
这里我们有一个C++的导出方法,里面会传递一个结构体,并且是一个嵌套结构体。
相信大部分人都看不出来有什么问题,在我传递参数到C++内部后,我发现sCalleeId的值是空的。于是开始查找问题了。
定位问题
1.排除dll的格式问题
我通过调用无参、调用简单参数的方法,发现能够正常运行,所以dll应该是好的。
2.排除参数格式问题
通过对比C#中定义的结构体以及C++的头文件定义,结构体的定义并没有问题。
3.确认是传递时出的问题
我通过手动计算C++中结构体的大小,发现我用C#定义的结构体占用的内存多了3个字节!没错,就是这3个字节导致的。
那么这3个字节是哪里来的呢?第一反应就是字节对齐的问题(开发的经验啊)。
于是我把bool类型改为了int类型,使用int.MaxValue进行赋值。在测试后发现,C++能够读取到字符串了。看来我定位到了问题所在。
解决问题
因为知道了是因为1个字节的bool在传递过程中占用4个字节,那么我们想办法移除掉后面3个字节就好了,好在网上有答案,不然我都想自己toBytes去处理???
我加上了一个属性,如下图,据说这样就是单字节对齐
再然后,我运行发现内存占用仍然多了3个字节。于是我在国外网站找到了完整的方法,这东西要配套使用啊。
终于解决问题了!
结论
C#调用C++并且传递结构体参数的时候,需要注意4K对齐的问题,否则可能导致传参失败,所以最好是将bool类型放到最后,不要在一开始,这样随你怎么对齐哈哈哈。
在处理bool类型对齐时,这两个东西一定要配套使用