在写一个接口,调用设备读取银行卡信息,调用的是一个读卡器提供的dll。
接口文档如下:
```c++
int __stdcall ReadPBOCGenARQC(char *Field2, char *Field35, char *Field36,char * ARQC, char *ErrMsg);
接口描述:
该接口不是立刻返回,循环读卡,流程请参考指令扫码流程 ,超时时间30秒。
入参: 无
出参:
Field2:银联2域数据,数据转换为ASCII(主账号)
Field35:银联35域数据,数据转换为ASCII
Field36:银联36域数据,数据转换为ASCII
ARQC:银联55域数据,数据转换为ASCII
返回: 0成功 非零失败
错误:ErrMsg(补充错误信息)
我的代码:
```c#
[DllImport("HealthyCarder.dll", EntryPoint = "ReadPBOCGenARQC", CallingConvention = CallingConvention.Cdecl)]
public static extern int ReadPBOCGenARQC(StringBuilder Field2, StringBuilder Field35, StringBuilder Field36, StringBuilder ARQC, StringBuilder ErrMsg);
运行的时候提示:其他信息: 对 PInvoke 函数“WqReadCard!WqReadCard.clsReadCard::ReadPBOCGenARQC”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
CallingConvention = CallingConvention.Cdecl 这段加不加,都报错。麻烦帮忙看看,指导一下。。谢谢
C#对应char*的数据类型是IntPtr啊
明明是stdcall,你加上 cdecl 干嘛
CallingConvention = CallingConvention.Stdcall 看看
【以下回答由 GPT 生成】
这个问题可能是因为C#代码中的PInvoke签名与C++动态库中的函数签名不匹配导致的。根据接口描述中的信息,我们可以看到接口是以__stdcall调用约定被声明的,而C#默认使用的是__cdecl调用约定。此外,C++的char *类型在C#中应该使用StringBuilder来代替。
为了解决这个问题,可以尝试以下步骤:
[DllImport("HealthyCarder.dll", EntryPoint = "ReadPBOCGenARQC", CallingConvention = CallingConvention.StdCall)]
public static extern int ReadPBOCGenARQC(StringBuilder Field2, StringBuilder Field35, StringBuilder Field36, StringBuilder ARQC, StringBuilder ErrMsg);
StringBuilder Field2 = new StringBuilder(1000);
StringBuilder Field35 = new StringBuilder(1000);
StringBuilder Field36 = new StringBuilder(1000);
StringBuilder ARQC = new StringBuilder(1000);
StringBuilder ErrMsg = new StringBuilder(1000);
int result = ReadPBOCGenARQC(Field2, Field35, Field36, ARQC, ErrMsg);
// 设置超时时间,单位为毫秒
int timeout = 30000;
// 获取当前时间的毫秒数
int startTime = Environment.TickCount;
while (result != 0 && (Environment.TickCount - startTime) < timeout)
{
// 继续读卡操作
result = ReadPBOCGenARQC(Field2, Field35, Field36, ARQC, ErrMsg);
}
if (result == 0)
{
// 成功读取银行卡信息
string field2 = Field2.ToString();
string field35 = Field35.ToString();
string field36 = Field36.ToString();
string arqc = ARQC.ToString();
}
else
{
// 读卡失败,查看错误信息
string errMsg = ErrMsg.ToString();
}
通过以上步骤,我们尝试将C#的PInvoke签名与C++函数签名匹配,并在调用接口时进行循环读卡操作,直到超时或成功读取到银行卡信息为止。希望这些步骤能够帮助你解决问题。如果问题仍然存在,请回复告知详细情况。