首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

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

2012-12-14 
Delphi的结构体传值转成vb的写法问题//发依时利690消费卡function WriteER690Card(aSectorNo: ShortInt P

Delphi的结构体传值转成vb的写法问题
//发依时利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


[最优解释]
如果没理解错的话,“结构体传值” 的意思是将整个 TER690CardInfo 结构都压入参数堆栈吧!
这是相同的问题
  http://topic.csdn.net/u/20080410/10/85235b13-0af8-4938-8974-9b5e3687d548.html
需要将所有结构的成员全部用通过变通的方式声明在 VB 中,supergreenbean 还给出了合并 4 字节的方法。

总之这样的函数原型是不适合 API 调用的;常用的 API 传结构的方式,总是传指针的。
[其他解释]

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


Private Type YSL_TER690CardInfo
    cardno As Long                   '卡号
    CardName As String * 8 '姓名
    CardBalance As Integer               '卡余额(单位分)……
为什么你的Private Type YSL_TER690CardInfo2下声明的都是byte呢,明显的不可能啊,至少有integer还有string类型吧,你自己对照delphi的做类型修改
[其他解释]
完整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;
[其他解释]
VB6对于结构体默认都是传引用的。你把那个Byref去掉看看。还有你的返回类型怎么是Byte的?你的Delphi中的声明是Boolean的啊?
[其他解释]
我声明了二个结构体,一个是按原型定义的,一个是按byte转换后的,无论是原型的还是转换后的都一样的。我用读卡的过程读数据进来,与delphi的过程是一样的(byte和非byte都能正确读入)。估计重点不是在结构体的定义上,是传值与传址的区别
[其他解释]
感谢Tiger_Zhao,看了下您说的贴子,应该是厂家没写好,只能先看上面的方法测试下,之后告诉您结果。
[其他解释]
delphi声明为byte是因为vb中的boolean与delphi中的值不一样,一个是1,一个是-1

热点排行