C#中调用C++写的DLL注意事项

来源:互联网 发布:ubuntu 16.04 selinux 编辑:程序博客网 时间:2024/05/17 00:07
C#中调用C++写的DLL
 

最近在写毕业设计,硬件模块儿的功能都封装到Dll里面了,当初想C#调用Dll也不一样easy(c#就看了一天就开始做了),可是等到该使用的时候发现了问题,结构体...就是这个,因为要传递结构体数组,结果死活是搞不定,只是能得到一组数据。试了网上的很多方案,包括IntPtr这些,可是仍不行,就这样折腾了三四天,其实这三四天里面一直想把结构体单独拿出来,做Demo测试可一直存着侥幸心理,没下手做。今天实在是受不了就安心做,把结构体的成员逐渐增加,这样试,嘿嘿,最终还是给让我发现了问题,MD,有个小结构体的字节没对齐。对齐之后就OK了,demo上能跑了。

1.如果c++生成的DLL需要被C#调用,那么在c++的结构体中,字符串应用char(WCHAR)类型,避免使用stirng,CString,在C#中声明这个结构的时候,对应的使用string类型但是必须指明string的长度。
2.如果被调用的函数中需要传递结构体指针,在c#中声明函数的时候加上out或者ref标志,如果要传递的是结构体数组,在这种情况下,如果结构体中并不包含其他的结构体或者包含的结构体的字节是对齐的,那么声明函数的时候加上[In,Out]即可。
如果被包含的结构体字节是未对齐的就无法得到正确结果。(字节对齐的可g.cn)

补充下关于字符串操作的:

3.如果需要从Dll中返回单个字符串,用如下调用方式
C#:
 [DllImport("PInvokeDll.dll", SetLastError = true , CharSet=CharSet.Unicode)]
 public static extern void StrTest1([In,Out]char[] str);

Dll:
void StrTest1(WCHAR* str);

4.如果需要从Dll中返回字符串数组,用如下调用方式(暂时想到用结构体封装的方式)
c#:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct struct4
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string name;
    };

[DllImport("PInvokeDll.dll", SetLastError = true , CharSet=CharSet.Unicode)]
public static extern void StrTest2([In,Out]struct4[] str , int len);

DLL:
struct struct4
{
 WCHAR name[20];
};
void StrTest2(struct struct4* str , int len);

 

文献来源于:http://blog.sina.com.cn/s/blog_6f9f12990100q6d0.html

原创粉丝点击