Delphi的结构体传值转成vb的写法问题

大帮手软件 2012-04-01 11:05:49
//发依时利690消费卡
function WriteER690Card(aSectorNo: ShortInt; PwdA: PChar; ER690CardInfo: TER690CardInfo): Boolean; stdcall; external ERTransDLL;
//读依时利690消费卡
function ReadER690Card(aSectorNo: ShortInt; PwdA: PChar; var ER690CardInfo: TER690CardInfo): Boolean; stdcall; external ERTransDLL;

读卡的转vb没有问题,写卡的因是对结构体传值的,vb的结构体只允许传址,该如何声明呢。

我是这样写的:
Private Declare Function YSL_WriteER690Card Lib "YSL_ERTrans.dll" Alias "WriteER690Card" (ByVal aSectorNo As Byte, ByVal PwdA As String, ByRef ER690CardInfo As YSL_TER690CardInfo) As Byte

...全文
151 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2012-04-02
  • 打赏
  • 举报
回复
如果没理解错的话,“结构体传值” 的意思是将整个 TER690CardInfo 结构都压入参数堆栈吧!
这是相同的问题
  http://topic.csdn.net/u/20080410/10/85235b13-0af8-4938-8974-9b5e3687d548.html
需要将所有结构的成员全部用通过变通的方式声明在 VB 中,supergreenbean 还给出了合并 4 字节的方法。

总之这样的函数原型是不适合 API 调用的;常用的 API 传结构的方式,总是传指针的。
无·法 2012-04-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

完整VB代码如下,麻烦帮看下是什么原因导致出现错误“DLL调用约定错误”


Private Type YSL_TER690CardInfo
cardno As Long '卡号
CardName As String * 8 '姓名
CardBalance As Integer '卡余额(单位分)……
[/Quote]为什么你的Private Type YSL_TER690CardInfo2下声明的都是byte呢,明显的不可能啊,至少有integer还有string类型吧,你自己对照delphi的做类型修改
大帮手软件 2012-04-02
  • 打赏
  • 举报
回复
完整VB代码如下,麻烦帮看下是什么原因导致出现错误“DLL调用约定错误”


Private Type YSL_TER690CardInfo
cardno As Long '卡号
CardName As String * 8 '姓名
CardBalance As Integer '卡余额(单位分)
ChargeTimes As Integer '充值次数
OverPwd As Long '超额密码
DayMoney As Integer '日累计
Period As Byte '消费时段
PeriodCount As Byte '时段次数
MonthDay As Integer '消费月日
OrderGroup As Integer '订餐分组(0-15组)
OrderMonth As Byte '订餐月
OrderDay As Byte '订餐日
OrderListType As Byte '订餐表类型
CycleMealFlag As Byte '重复消费标志
OrderList(0 To 7) As Byte '订餐表
'V1.35新增
ReservedFlag As Byte '保留,补贴批次
Privillege As Byte '权限
EnterpriseID As Long '企业ID,按BCD格式存储
End Type

Private Type YSL_TER690CardInfo2
cardno(0 To 3) As Byte '卡号
CardName(0 To 7) As Byte '姓名
CardBalance(0 To 1) As Byte '卡余额(单位分)
ChargeTimes(0 To 1) As Byte '充值次数
OverPwd(0 To 3) As Byte '超额密码
DayMoney(0 To 1) As Byte '日累计
Period As Byte '消费时段
PeriodCount As Byte '时段次数
MonthDay(0 To 1) As Byte '消费月日
OrderGroup(0 To 1) As Byte '订餐分组(0-15组)
OrderMonth As Byte '订餐月
OrderDay As Byte '订餐日
OrderListType As Byte '订餐表类型
CycleMealFlag As Byte '重复消费标志
OrderList(0 To 7) As Byte '订餐表
'V1.35新增
ReservedFlag As Byte '保留,补贴批次
Privillege As Byte '权限
EnterpriseID(0 To 3) As Byte '企业ID,按BCD格式存储
End Type

Private Declare Function YSL_OpenReaderAfterParam Lib "YSL_ERTrans.dll" Alias "OpenReaderAfterParam" (ByVal CommStyle As Integer, ByVal ClockModel As Integer, ByVal ComPort As Integer, ByVal BaudRate As Integer) As Byte

'读依时利690消费卡
Private Declare Function YSL_ReadER690Card Lib "YSL_ERTrans.dll" Alias "ReadER690Card" (ByVal aSectorNo As Byte, ByVal PwdA As String, ByRef ER690CardInfo As YSL_TER690CardInfo) As Byte


'发依时利690消费卡(即1.0消费卡)
Private Declare Function YSL_WriteER690Card Lib "YSL_ERTrans.dll" Alias "WriteER690Card" (ByVal aSectorNo As Byte, ByVal PwdA As String, ByRef ER690CardInfo As YSL_TER690CardInfo) As Boolean
Private Declare Function YSL_WriteER690Card2 Lib "YSL_ERTrans.dll" Alias "WriteER690Card" (ByVal aSectorNo As Byte, ByVal PwdA As String, ByRef ER690CardInfo As YSL_TER690CardInfo2) As Byte

Private Sub Form_Load()
Dim W_YSL_TER690CardInfo As YSL_TER690CardInfo
Dim W_YSL_TER690CardInfo2 As YSL_TER690CardInfo2
Dim W_Tmp1 As String
Dim W_A As Byte
W_A = 2
W_Tmp1 = "22222"
MsgBox YSL_OpenReaderAfterParam(0, 900, 5, 9600)
MsgBox YSL_WriteER690Card(W_A, W_Tmp1, W_YSL_TER690CardInfo) '此时会出现 DLL调用约定错误
MsgBox YSL_WriteER690Card2(W_A, W_Tmp1, W_YSL_TER690CardInfo2) '此时会出现 DLL调用约定错误
End Sub


delphi原代码:

TOrderList=packed array[0..7] of Byte;

TER690CardInfo=packed record
CardNo: DWORD; //卡号
CardName: array [0..7] of Char; //姓名
CardBalance: Word; //卡余额(单位分)
ChargeTimes: Word; //充值次数
OverPwd: DWORD; //超额密码
DayMoney: Word; //日累计
Period: Byte; //消费时段
PeriodCount: Byte; //时段次数
MonthDay: Word; //消费月日
OrderGroup: Word; //订餐分组(0-15组)
OrderMonth: Byte; //订餐月
OrderDay: Byte; //订餐日
OrderListType: Byte; //订餐表类型
CycleMealFlag: Byte; //重复消费标志
OrderList: TOrderList; //订餐表
{V1.35新增}
ReservedFlag: Byte; //保留,补贴批次
Privillege: Byte; //权限
EnterpriseID: DWORD; //企业ID,按BCD格式存储

end;

//发依时利690消费卡
function WriteER690Card(aSectorNo: ShortInt; PwdA: PChar; ER690CardInfo: TER690CardInfo): Boolean; stdcall; external ERTransDLL;
//读依时利690消费卡
function ReadER690Card(aSectorNo: ShortInt; PwdA: PChar; var ER690CardInfo: TER690CardInfo): Boolean; stdcall; external ERTransDLL;
//打开发卡器,在连接发卡器之前需要装载参数LoadCardParamV2
function OpenReaderAfterParam(CommStyle, ClockModel, ComPort, BaudRate: Integer): Boolean; stdcall; external ERTransDLL;
大帮手软件 2012-04-02
  • 打赏
  • 举报
回复
delphi声明为byte是因为vb中的boolean与delphi中的值不一样,一个是1,一个是-1
大帮手软件 2012-04-02
  • 打赏
  • 举报
回复
感谢Tiger_Zhao,看了下您说的贴子,应该是厂家没写好,只能先看上面的方法测试下,之后告诉您结果。
大帮手软件 2012-04-02
  • 打赏
  • 举报
回复
我声明了二个结构体,一个是按原型定义的,一个是按byte转换后的,无论是原型的还是转换后的都一样的。我用读卡的过程读数据进来,与delphi的过程是一样的(byte和非byte都能正确读入)。估计重点不是在结构体的定义上,是传值与传址的区别
贝隆 2012-04-02
  • 打赏
  • 举报
回复
VB6对于结构体默认都是传引用的。你把那个Byref去掉看看。还有你的返回类型怎么是Byte的?你的Delphi中的声明是Boolean的啊?

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧