c#调用c++的dll,参数类型匹配有关问题
c#调用c++的dll,参数类型匹配问题
大家好,现有一个c++写好的dll文件,其中有一个函数如下:
UINT FncJobList (UINT uLogonID, UINT uOption,UINT uJobType,LPTSTR lpstrJobName,LPTSTR lpstrRevision,UINT uDataType,UINT UpperType,LPTSTR lpstrUpperName,LPDWORD lpdwListNum,LPBYTE *lpListData,LPDWORD lpdwListDataLen)
我需要在c#中调用这个C++方法,C#中引用这个方法的代码如下:
[DllImport(@"D:\Programs\OperateFlexa\OperateFlexa\bin\Debug\FNCJMACC.dll",CallingConvention=CallingConvention.StdCall)]
extern static uint FncJobList(uint uLogonID, uint uOption, uint uJobType, [MarshalAs(UnmanagedType.LPTStr)] string lptstrJobName, [MarshalAs(UnmanagedType.LPTStr)] string lpstrRevision, uint uDataType, uint uUpperType, [MarshalAs(UnmanagedType.LPTStr)] string lpstrUpperName, [MarshalAs(UnmanagedType.LPArray)] Int32[] lpdwListNum,ref IntPtr lpListData, [MarshalAs(UnmanagedType.LPArray)] Int32[] lpdwListDataLen);
执行后得不到数据,我想请大家帮我看看,是否是因为在c#中写的参数类型有问题,
1)C++中数据类型 LPTSTR 对应于C# 的数据类型是否为 [MarshalAs(UnmanagedType.LPTStr)] string
2)C++ 中的数据类型LPBYTE *(注意含指针*)对应于C#的数据类型是否为ref IntPtr
3)C++中的数据类型LPDWORD 对应于C#的数据类型是否为 [MarshalAs(UnmanagedType.LPArray)] Int32[]
------解决思路----------------------
第一个,字符指针,我是用intptr,字符数组我才用stirng
第二个,一般2级指针是做输出参数,ref intptr,应该可以,但是我都是直接用intptr,多做一次解指针就ok
第三个,word指针,我是用intptr,word数组可以考虑用int32[];
---------------
不建议用LPSTR LPDWORD这种宏。
LPSTR等字符宏 无法确定是宽字符还是单字节,建议直接改用char或wchar_t,
LPDWORD 等整型数据类型无法准确确定字节长度,建议用int32_t等定长的整型数据
------解决思路----------------------
至于lpListData这东西,我们很难知道他是什么(没有文档,我只能认为他是byte []),所以得自己根据他返回的datalen长度自己去计算字节大小,然后自己用marshal.copy把byte[]读处理(根据返回的名称,我大概猜到是个对象数组,至于这个对象的大小对应的size是多少我不得而知,所以我们无法确定后面到底需要读取多少字节出来,也不知道读出的byte[]应该如何解析,所以这部分工作需要你自己看他的api文档来确定)
大家好,现有一个c++写好的dll文件,其中有一个函数如下:
UINT FncJobList (UINT uLogonID, UINT uOption,UINT uJobType,LPTSTR lpstrJobName,LPTSTR lpstrRevision,UINT uDataType,UINT UpperType,LPTSTR lpstrUpperName,LPDWORD lpdwListNum,LPBYTE *lpListData,LPDWORD lpdwListDataLen)
我需要在c#中调用这个C++方法,C#中引用这个方法的代码如下:
[DllImport(@"D:\Programs\OperateFlexa\OperateFlexa\bin\Debug\FNCJMACC.dll",CallingConvention=CallingConvention.StdCall)]
extern static uint FncJobList(uint uLogonID, uint uOption, uint uJobType, [MarshalAs(UnmanagedType.LPTStr)] string lptstrJobName, [MarshalAs(UnmanagedType.LPTStr)] string lpstrRevision, uint uDataType, uint uUpperType, [MarshalAs(UnmanagedType.LPTStr)] string lpstrUpperName, [MarshalAs(UnmanagedType.LPArray)] Int32[] lpdwListNum,ref IntPtr lpListData, [MarshalAs(UnmanagedType.LPArray)] Int32[] lpdwListDataLen);
执行后得不到数据,我想请大家帮我看看,是否是因为在c#中写的参数类型有问题,
1)C++中数据类型 LPTSTR 对应于C# 的数据类型是否为 [MarshalAs(UnmanagedType.LPTStr)] string
2)C++ 中的数据类型LPBYTE *(注意含指针*)对应于C#的数据类型是否为ref IntPtr
3)C++中的数据类型LPDWORD 对应于C#的数据类型是否为 [MarshalAs(UnmanagedType.LPArray)] Int32[]
------解决思路----------------------
第一个,字符指针,我是用intptr,字符数组我才用stirng
第二个,一般2级指针是做输出参数,ref intptr,应该可以,但是我都是直接用intptr,多做一次解指针就ok
第三个,word指针,我是用intptr,word数组可以考虑用int32[];
---------------
不建议用LPSTR LPDWORD这种宏。
LPSTR等字符宏 无法确定是宽字符还是单字节,建议直接改用char或wchar_t,
LPDWORD 等整型数据类型无法准确确定字节长度,建议用int32_t等定长的整型数据
------解决思路----------------------
至于lpListData这东西,我们很难知道他是什么(没有文档,我只能认为他是byte []),所以得自己根据他返回的datalen长度自己去计算字节大小,然后自己用marshal.copy把byte[]读处理(根据返回的名称,我大概猜到是个对象数组,至于这个对象的大小对应的size是多少我不得而知,所以我们无法确定后面到底需要读取多少字节出来,也不知道读出的byte[]应该如何解析,所以这部分工作需要你自己看他的api文档来确定)