二代证、很奇怪的Dll调用(附汇编代码)
碰到一个很奇怪的问题,百思不得其解,特向高手请教
开发工具:VB6
程序:二代证的读取
条件:读卡器、二代证、stdapi.dll文件、厂家的读卡程序(VB编的)、没有SDK资料
问题:在使用SDT_ReadBaseMsg读取信息时返回“Dll调用约定错误”
函数原型(网络资料):int SDT_ReadBaseMsg(
int iPort,
unsigned char *pucCHMsg,
unsigned int *puiCHMsgLen,
unsigned char *pucPHMsg,
unsigned int *puiPHMsgLen,
int iIfOpen);
南疯大侠的C#声明(参考:http://www.cnblogs.com/name-lh/archive/2007/04/10/324003.html):
public static extern int SDT_ReadBaseMsg(
int iPortID,
string pucCHMsg,
ref int puiCHMsgLen,
string pucPHMsg,
ref int puiPHMsgLen,
int iIfOpen);
VB声明(自己翻译的):Private Declare Function SDT_ReadBaseMsg Lib "sdtapi.dll" (
ByVal iPort As Long,
ByRef pucCHMsg As String,
ByRef pucCHMsgLen As Long,
ByRef puvPHMsg As String,
ByRef puvPHMsgLen As Long,
ByVal iIfOpen As Long)
问题在于不管如何改变参数类型,总是报错,我试过全改成Any,也不行,Byte和数组也不行,改成Long然后传入PtrVar()也不行,厂家的读卡程序一切正常
这是厂家程序调用的汇编代码:
:004F61A7 0B47001800 ImpAdCallI2 ;Call ptr_004F2874; check stack 0018; Push EAX
:004F61AC 706EFF FStI2 ;Pop WORD [LOCAL_0092]
:004F61AF 3C SetLastSystemError ;Kernel GetLastError
:004F61B0 6B6EFF FLdI2 ;Push WORD [LOCAL_0092]
:004F61B3 F39000 LitI2 ;Push 0090
:004F61B6 C6 EqI2 ;
:004F61B7 1CF906 BranchF ;If Pop=0 then ESI=004F66A1
:004F61BA 222400 ImpAdLdPr ;
:004F61BD 895000 MemLdI2 ;Push WORD [[SR]+0050]
:004F61C0 F400 LitI2_Byte ;Push 00
:004F61C2 C6 EqI2 ;
:004F61C3 1C4802 BranchF ;If Pop=0 then ESI=004F61F0
:004F61C6 F500000000 LitI4 ;Push 00000000
:004F61CB F508000000 LitI4 ;Push 00000008
:004F61D0 054600 ImpAdLdRf ;Push ptr
:004F61D3 5968FF PopTmpLdAdStr ;
:004F61D6 4D58FF1160 CVarRef ;
:004F61DB 0448FF FLdRfVar ;Push LOCAL_00B8
请各位高手不吝赐教!
[解决办法]
unsigned char对于的是Byte,虽然使用string也可以接收数据,但是需要预先分配空间。unsigned int *类似的倒是可以写太 Byref xx as Long
[解决办法]
用的是哪家公司的读卡器?
最近也做过身份证读取的,不过硬件厂商直接提供了一个Ocx,所以很快就搞定
我试了一下C#部分的是可以读到相关信息,确认一下前面几个部分是否已成功?
比如SDT_OpenPort、SDT_StartFindIDCard、SDT_SelectIDCard
[解决办法]
哦,忽略了一点儿东西。试试:
Private Declare Function SDT_ReadBaseMsg Lib "sdtapi.dll" (
ByVal iPort As Long,
ByVal pucCHMsg As String,
ByRef pucCHMsgLen As Long,
ByVal puvPHMsg As String,
ByRef puvPHMsgLen As Long,
ByVal iIfOpen As Long) As Long
或者
Private Declare Function SDT_ReadBaseMsg Lib "sdtapi.dll" (
ByVal iPort As Long,
ByRef pucCHMsg As Byte,
ByRef pucCHMsgLen As Long,
ByRef puvPHMsg As Byte,
ByRef puvPHMsgLen As Long,
ByVal iIfOpen As Long) As Long
返回值的类型要声明一下。