以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.com/bbs/index.asp)
--  专家坐堂  (http://foxtable.com/bbs/list.asp?boardid=2)
----  全部代码中字符串指针如何处理?  (http://foxtable.com/bbs/dispbbs.asp?boardid=2&id=59318)

--  作者:mojo
--  发布时间:2014/11/2 0:42:00
--  全部代码中字符串指针如何处理?

需要在FT的全局代码使用下面的DLL库函数。

long __stdcall dc_load_key  ( long  icdev, unsigned char  _Mode, unsigned char  _SecNr, unsigned char *  _NKey )
在FT的全局代码中编写成如下格式:
Public Declare Function dc_load_key Lib "Trf32.dll" (ByVal icdev As Long, ByVal mode%, ByVal secnr%, ByRef nkey As string) As Integer
但是在程序运行中会出现下面的错误:
.NET Framework 版本:2.0.50727.3655
Foxtable 版本:2014.7.26.1
错误所在事件:窗口,卡操作,Button2,Click
详细错误信息:
尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
感觉主要原因还是字符串指针传递有问题。

dim Hexkey as string

Hexkey = "ffffff"
secnr = 1
Result = dc_load_key(Vars("IcDev"),  0, 1, Hexkey)

 
但是FT中怎么使用ByVal for string呢?
哪位专家能够指教?

--  作者:有点甜
--  发布时间:2014/11/2 9:43:00
--  

试试这样

 

Public Declare Function dc_load_key Lib "Trf32.dll" (ByVal icdev As Long, ByVal mode, ByVal secnr, ByRef nkey As StringBuilder) As Long

 

调用

 

Dim Hexkey As new StringBuilder
Hexkey.append("ffffff")
secnr = 1
Result = dc_load_key(Vars("IcDev"),  0, 1, Hexkey)


--  作者:mojo
--  发布时间:2014/11/2 13:11:00
--  

非常感谢你的回答,有了进展,可是IC卡的密码校验出错。

不知道char*参数传递是否有问题,我在VB下面基本可以调通。

 

Dim Hexkey As new Stringbuilder

Hexkey.append("ffffffffffffffffffffffff")
secnr = 1 \'1扇区
PWmode = 0 \'密码A
tb2.text = Hexkey.Tostring
Result = dc_load_key_hex(Vars("IcDev"),  PWmode, secnr, Hexkey)  \'装载1扇区的密码到读写器,这和后面要
If Result < 0 Then                                        \'校验1扇区的密码是相对应的
      MessageBox.Show("密码装载错误!", "提示")
      Exit Sub
End If

Result = dc_authentication(Vars("IcDev"), PWmode, secnr)  \'核对卡密码
If Result < 0 Then
      MessageBox.Show("密码校验错误!", "提示")
      Exit Sub
End If

 

总是返回密码校验错误。

[此贴子已经被作者于2014-11-2 13:12:22编辑过]

--  作者:有点甜
--  发布时间:2014/11/2 14:11:00
--  

 这样试试

 

Dim Hexkey As new Stringbuilder(24)

Hexkey.append("ffffffffffffffffffffffff")

 

 再不行,就尝试用char[]数组作为参数。


--  作者:mojo
--  发布时间:2014/11/2 14:40:00
--  

DLL中函数定义如下:

long __stdcall dc_load_key_hex ( long  icdev,
unsigned char  _Mode,
unsigned char  _SecNr,
unsigned char *  _NKey  
)

下载设备密码(HEX形式)

说明:
dc_load_key函数的HEX形式,字符串数据将以HEX形式传递。

 

如果是stringbuilder,FT中定义如下,但是进一步校验密码出错。

Public Declare Function dc_load_key_hex Lib "Trf32.dll" (ByVal icdev As Long, ByVal mode%, ByVal secnr%, ByRef nkey As Stringbuilder) As Long

 

dim nkey as new Stringbuilder

(dim nkey as new Stringbuilder(24),也尝试过了,不工作)

 

如果是数组的话,FT中是否定义如下?

Public Declare Function dc_load_key_hex Lib "Trf32.dll" (ByVal icdev As Long, ByVal mode%, ByVal secnr%, ByRef nkey As Byte) As Long

 

dim nkey(12) as byte

nkey(0)=102

nkey(1)=102

....

我昨天也尝试过,但是直接内存访问出错了,我可以在试一试。

如何把数组的指针传递过去呢?下面这样对吗?

Result = dc_load_key_hex(Vars("IcDev"),  PWmode, secnr, nkey(0))

[此贴子已经被作者于2014-11-2 14:52:21编辑过]

--  作者:有点甜
--  发布时间:2014/11/2 14:51:00
--  
 你的设备有没有vb.net 或者 c#等的例子?如果有,就照抄
--  作者:有点甜
--  发布时间:2014/11/2 14:54:00
--  

 如果用数组,这样定义

 

Public Declare Function dc_load_key_hex Lib "Trf32.dll" (ByVal icdev As Long, ByVal mode%, ByVal secnr%, ByRef nkey As Byte()) As Long


--  作者:mojo
--  发布时间:2014/11/2 14:58:00
--  

VB下面我都调试通过了,下面的两种方法都可以。

1,使用String,结合ByVal传递String的指针

hexkey = "ffffffffffff"
st = dc_load_key_hex(ByVal icdev, 0, 1, ByVal hexkey)  \'装载1扇区的密码到读写器,这和后面要

 

2,使用byte数组,传递数组第一位的地址进去。

Dim hexkey(12) As Byte
hexkey(0) = 102
hexkey(1) = 102
hexkey(2) = 102
hexkey(3) = 102
hexkey(4) = 102
hexkey(5) = 102
hexkey(6) = 102
hexkey(7) = 102
hexkey(8) = 102
hexkey(9) = 102
hexkey(10) = 102
hexkey(11) = 102
st = dc_load_key_hex(ByVal icdev, 0, 1, hexkey(0))  \'装载1扇区的密码到读写器

用下面的方式声明

Declare Function dc_load_key_hex Lib "Trf32.dll" (ByVal icdev As Long, ByVal mode%, ByVal secnr%, ByRef nkey As Byte) As Integer

 

但是这两种方法在FT中都不工作。

FT不支持关键字ByVal,也不确定数组指针怎么传递的。

[此贴子已经被作者于2014-11-2 15:08:08编辑过]

--  作者:有点甜
--  发布时间:2014/11/2 15:03:00
--  
 看楼上
--  作者:mojo
--  发布时间:2014/11/2 20:59:00
--  

终于好了,主要注意下面几点:

1,即便是参数是字符串的指针,也必须使用ByVal,如果使用ByRef,程序会崩溃

Public Declare Function dc_read Lib "Trf32.dll" (ByVal icdev As Integer, ByVal adr%, ByVal sdata As Byte()) As Integer

2,程序中使用字节数组即可

Dim dataread_byte(16) As Byte

Result = dc_read(Vars("IcDev"),blknr, dataread_byte)    \'读卡内的数据

 

现在实现了身份证的读写和M1/S70卡的读写操作。