首页 新闻 会员 周边

C# 调用C/C++ dll

0
悬赏园豆:100 [已解决问题] 解决于 2012-08-02 10:06

C/C++ 

DWORD _stdcall GetSerialNum
(
IN HANDLE hCard, 
OUT BYTE bSerial[NUMLEN] 
);

Byte的定义是typedef unsigned char BYTE;

我写的:
  [DllImport("HS.dll", EntryPoint = "GetSerialNum")]
  public static extern uint GetSerialNum([In]uint handl, [MarshalAs(UnmanagedType.LPArray)] byte[] data);

调用方法:
  byte[] array= new byte[8];
  Common.GetSerialNum(KeyHandle, array);

返回来的array 我用Encoding.Default.GetString(array)转换,拿到的是乱码

 

用Encoding.Unicode.GetString(array)拿到的是

用StringBuilder也是获得上面的值。。。。。

以为长度问题,把array=new byte[255],也没用

我想就是我传参数的问题了,OUT BYTE bSerial[NUMLEN]  

这应该传什么呢。

李晔的主页 李晔 | 初学一级 | 园豆:94
提问于:2012-07-14 02:49
< >
分享
最佳答案
0

上次这个问题就说过吧,你确定 bSerial[NUMLEN] 返回的是字符串吗?

我没猜错的话:

DWORD _stdcall GetSerialNum(IN HANDLE hCard,OUT BYTE bSerial[NUMLEN]

hCard:一个句柄;

bSerial:大小为 NUMLEN 的字节数组

返回值:实际填充到 bSerial 数组的字节数。

DllImport 中的 CharSet 不会影响调用结果,因为返回的是字节数组,表明在 HS.dll 内部已经将字符串转换为了与编码无关的字节数组,编码可能是MBCS或UNICODE的一种。

收获园豆:50
Launcher | 高人七级 |园豆:45045 | 2012-07-14 10:34

我就是不确定 bSerial[NUMLEN]返回的是什么,也不知道要传什么参数。。。我也试过传byte[] 啊,结果也一样

李晔 | 园豆:94 (初学一级) | 2012-07-14 10:47

@李晔: 你没看明白,你拿到 BYTE[] 数组后,是不是要编码为字符串,这是由 API 作者决定的,用什么编码方式转换为字符串,也是 API 作者决定的。一般我们在C++中如果要把字符串转换为字节数组,会如下做:

LPCTSTR pszStr = _T("sdfdsfsdf");   // 以 /0 结束的字符串。

DWORD dwLength = _tcslen(pszStr) * sizeof(TCHAR);   // 字符串的长度

LPBYTE pbData = (LPCTSTR)pszStr;

那么在 C++ 中要得到原字符串,很简单:

LPCSTR pszStr2 = (LPCTSTR)pbData;

而在 C# 中,如果确定编码方式(MBCS或UNICODE),那么也能通过string类型来强制转换,或则通过 Encoding.GetString() 来转化,如果定义了 _UNICODE,那么你需要使用 Encoding.Unicode.GetString();

如果 pbData 并不是通过字符串强制转换未来的,那么就比较麻烦,你必须清楚的知道 API 作者到底以什么方式往 byte[] 数组里写了什么值。

Launcher | 园豆:45045 (高人七级) | 2012-07-14 11:26
其他回答(1)
0

 [DllImport("HS.dll", EntryPoint = "GetSerialNum")]还有一个CharSet吧!试试!!

收获园豆:25
Angkor--:-- | 园豆:1086 (小虾三级) | 2012-07-14 07:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册