有一读卡器设备,提供二次开发使用的DLL文件。但提供的实例只有VB代码,现需要迁移至VB .NET 2008。
VB6中的相关代码:
'数据加密运算
Public Declare Sub cpudata3desenc Lib "OUR_MIFARE.dll" (ByVal indatabuf As Long, ByVal indatalen As Long, ByVal key As Long, ByVal keylen As Byte, ByVal outdatabuf As Long, ByVal outdatalen As Long)
Dim j As Integer
Dim keybuf(0 To 15) As Byte '密钥
Dim keylen As Byte '密钥长度,8或16个字节
Dim sendbuf(0 To 255) As Byte '明文数据缓冲
Dim calcbuf(0 To 255) As Byte '计算结果
Dim calcbuflen As Long '计算结果
'中间过程省略
cpudata3desenc VarPtr(sendbuf(0)), j, VarPtr(keybuf(0)), keylen, VarPtr(calcbuf(0)), VarPtr(calcbuflen)
观察VB6代码,调用DLL过程cpudata3desenc时,6个参数中有4个都使用了VarPtr。但是VB .NET中并没有VarPtr这个函数,所以在声明过程时,需要改用“ByRef”来对应;没有使用VarPtr的参数,仍然使用“ByVal”。
<DllImport("OUR_MIFARE.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Public Sub cpudata3desenc(ByRef indatabuf As Byte, ByVal indatalen As Int16, ByRef key As Byte, ByVal keylen As Byte, ByRef outdatabuf As Byte, ByRef outdatalen As Long)
End Sub
如果DLL文件是32位的,就需要设置Visual Studio的生成(编译)平台为x86。但似乎在VS2008 Express里找不到这个选项。如果是临时调试,可以使用32位操作系统安装VS2008 Express。但这种临时方法生成的exe文件复制到X64系统内无法正常工作,调用DLL时会提示“试图加载格式不正确的程序 HRESULT:0x8007000B”。
可以使用VS 2010。打开项目(并转换)后,在右上的“解决方案资源管理器”窗口中,右键项目名称,选择属性。在“编译”选项卡中,应该可以看到“配置”和“活动平台”两个下拉选单。如果“活动平台”中只有Any CPU的话,点击最上面的“生成”菜单,选择“配置管理器”,为“活动解决方案平台”新建一个x86项目。(之后生成的exe文件目录会变化,注意把DLL文件拷贝过去。)
(好像是VB .NET和C#的设置方式不太一样,没详细考证过,我这里以VB .NET为例。)
还需要注意VB6和VB .NET数据类型的转换。如VB6中的Integer占用2字节(16位);Long占用4字节(32位)。但VB .NET中的Integer占用4字节(32位);Long占用8字节(64位)。
为了避免来回看代码产生混淆,在VB .NET中可以使用Int16、Int32作为数据类型,清晰准确。
修改后的VB .NET代码如下:
Dim KeyAsBytes(15), ClearTextAsBytes(255), EncTextAsBytes(255) As Byte
Dim ClearTextLen As Int16
Dim KeyLen As Byte
Dim EncTextLen As Int32
'中间过程省略
cpudata3desenc(ClearTextAsBytes(0), ClearTextLen, KeyAsBytes(0), KeyLen, EncTextAsBytes(0), EncTextLen)