DllImport("GEA00001.dll", EntryPoint = "HSListReaders", CharSet = CharSet.Ansi)]
public static extern uint HSListReaders(System.Text.StringBuilder p, ref uint pdwReaderNameLen, ref uint pdwReaderNum); [DllImport("GEA00001.dll", EntryPoint = "HSConnectDev", CharSet = CharSet.Ansi)]
public static extern uint HSConnectDev(String szDevName, ref IntPtr hCard);一出一进编码要一样。
public static extern uint HSListReaders(System.Text.StringBuilder p, ref uint pdwReaderNameLen, ref uint pdwReaderNum); [DllImport("GEA00001.dll", EntryPoint = "HSConnectDev", CharSet = CharSet.Ansi)]
public static extern uint HSConnectDev(String szDevName, ref IntPtr hCard);一出一进编码要一样。
public static extern uint HSConnectDev(String szDevName, [Out] out IntPtr hCard);
如果是零,可能有错误,
如果大于一,返回字符串可能是多字符串。
[DllImport("GEA00001.dll", EntryPoint = "HSConnectDev", CharSet = CharSet.Auto)]
改成Ansi。
另外如果读卡器没有问题的话,你看看读到的设备名称是不是正确,末尾是不是有不可显示的字符什么的。
再试试StringBuilder的编码格式,也许不正确。
编码改为Ansi,是可以,但是返回的LPSTR 中有“/0”,在转入到StringBuilder遇到“/0”之后就结束,不再继续把值传入到StringBuilder中,一共有八个值,只能取到第一个
如果使用Unicode或者Auto,等到的值又是乱码,求大家帮忙
void Test()
{
string multiString = "hello" + (char)0 + "world" + (char)0 + (char)0;
byte[] bytes = Encoding.Default.GetBytes(multiString);
List<string> strs = GetMultiString(bytes);
}static List<string> GetMultiString(byte[] bytes)
{
List<string> result = new List<string>();
for (int i = 0; i < bytes.Length; )
{
int j = Array.IndexOf<byte>(bytes, 0, i);
if (j == -1 || j - i < 2) break;
result.Add(Encoding.Default.GetString(bytes, i, j - i));
i = j + 1;
}
return result;
}
public static extern uint HSListReaders(IntPtr p,。IntPtr buffer = Marshal.AllocHGlobal(145);
HSListReaders(buffer,...
Marshal.Copy(buffer, bytes, 0, 145);
再把bytes按照'\0'分组,分别转换成string
也就是说,是以 NULL 为结尾的 字符串数组,最后以两个 NULL 为结尾的 BSTR 字符串。
你可以获取缓冲区后,自己枚举字符串数组。 private IEnumerable<string> PtrToStringBSTR(IntPtr ptr)
{
while (Marshal.ReadInt16(ptr) != 0)
{
string str = Marshal.PtrToStringUni(ptr);
ptr += (str.Length + 1) * 2;
yield return str;
}
}
private static extern int _GetBufferedMBSTR([In] IntPtr @this, [In, MarshalAs(UnmanagedType.I4)] int index, [In, Out] IntPtr buffer, [In] int size, [Out] out int length);
public string[] GetBufferedString(int index)
{
IntPtr buffer = Marshal.AllocCoTaskMem(256 * 2);
int length = 0;
try
{
_GetBufferedMBSTR(_basecpp, index, buffer, 256, out length);
return PtrToStringBSTR(buffer).ToArray();
}
finally
{
Marshal.FreeCoTaskMem(buffer);
}
}