调用外部dll的问题

liubocy 2005-06-06 11:18:59
程序中要用到HotelLock.dll中的几个函数,其中有个函数:
-----------------------------------------------
short __stdcall ReadCard(short *Rom, short *Pass, short *Buiding, short *Floor, short *District , short *Room, short *enOverride, short *FlatBit,short *TimeWindow,short *StartTime,short *EndTime);
功能:
读卡内容。
参数:
Rom : 卡号 .
Rom[0]: 卡号L。
Rom[1]: 卡号H。
Pass : N/A
Building : 楼号
Floor : 楼层
District : 区域
Room :
Room[0] = 有效房号,值为整数。
enOverride :
应用挂失标志: 1:不挂失,0: 挂失。
应用挂失是指起用新的密码代替旧密码(新卡覆盖旧卡),新密码的卡开门后,原来密码的旧卡失效,必须重新制卡才能开门。
FlatBit :
FlagBit[0] = 卡类型.
TimeWindow : N/A
StartTime :
有效起始时间:smallint类型数组,长度为5 。值为整数。
StartTime[0] = Year //如2003
StartTime[1] = Month //如 8
StartTime[2] = Date //如 8
StartTime[3] = Hour //如 18
StartTime[4] = Minute //如 0
EndTime:
有效终止时间:smallint类型数组,长度为5。
EndTime [0] = Year //如2003
EndTime [1] = Month //如 8
EndTime [2] = Date //如 9
EndTime [3] = Hour //如 12
EndTime [4] = Minute //如 0
---------------------------------------------
Declare Global External:
Function int ReadCard(int Rom[], int Pass[], int Buiding[], int Floor[], int District[] , int Room[], int enOverride[], int FlatBit[], int TimeWindow[], int StartTime[], int EndTime[]) Library "Hotellock.dll"
---------------------------------------------
调用:
integer re
int Rom[2]
int Pass[10]
int Buiding[1]
int Floor[1]
int District[1]
int Room[1]
int enOverride[1]
int FlatBit[1]
int TimeWindow[1]
int StartTime[5]
int EndTime[5]

re = ReadCard( Rom[], Pass[], Buiding[], Floor[], District[] , Room[], enOverride[], FlatBit[], TimeWindow[], StartTime[], EndTime[])
---------------------------------------------
这样取不到值,是不是Declare Global External中有错误?
...全文
319 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
liubocy 2005-06-07
  • 打赏
  • 举报
回复
用 wu_07 的第一种方法可以读出卡数据!

谢谢,谢谢一直关注和援手的朋友们!

-------------------------------

这几天有两个问题困扰着我,如梗在喉。我就厚着脸皮拖几天结贴了。见谅

问题1:pb机制中,传数组名进去函数调用是否获取的是数组的地址。如果是为什么我这里取不了值?

问题2:函数声明时,数组参数前加 ref ,在程序中为什么编译不通过?(结构参数前加ref倒是可以)如果程序中编译能通过的话,它能否就能够取值呢?

希望能够提供其他语言声明的外部函数的数据类型对照 pb 数据类型转换列表。

嘿嘿,我再加50分
lzheng2001 2005-06-07
  • 打赏
  • 举报
回复
狗狗的第二个方法我看不明白,能否解释一下?
wu_07 2005-06-07
  • 打赏
  • 举报
回复
你可以这样试一下,祝你好运

其中还有一个简单的函数:
-------------------------
short __stdcall ReadSystemPas(short *Password);
功能:从发卡机里读取客户卡密码。
参数:*PassWord:4个short 空间。
-------------------------
法一:

定义一个结构Password,由四个int成员构成

FUNCTION INT ReadSystemPas(ref Password p) Library "Hotellock.DLL"

-----------------------------------------------------------

法二:FUNCTION INT ReadSystemPas(long pt) Library "Hotellock.DLL"

然后每次pt+2(是加2吧?)用api函数CopyMemory到int变量中
lzheng2001 2005-06-07
  • 打赏
  • 举报
回复
两个函数应该是同一个问题,先用参数少的那个试验.
1.虽然short在c中相当于pb的int,但pb中声明API一般都用Long,即使是byte(0-255)在pb中一般也是声明为ulong

2.你肯定你定义的数组的长度没错才行,否则就很可能会出错. 或者试试用动态数组

li_d_s 2005-06-07
  • 打赏
  • 举报
回复
唉,用数组总是很难调试的,用c再包装一次吧
j9dai 2005-06-07
  • 打赏
  • 举报
回复
外部函数注意区分大小写:Library "HotelLock.dll"
liubocy 2005-06-07
  • 打赏
  • 举报
回复
试过,没什么作用

我想应该还是要加 ref 的吧
可是没 ref 的时候编译还能通过,加了反而报:
Bad argument list for function: readsystempas
的错误了

卡和读卡机是没问题的,用原版程序能读卡数据
lzheng2001 2005-06-07
  • 打赏
  • 举报
回复
问题1,用ref传的话,就是引用数组地址, 否则不是

问题2,数组前加ref也可以通过编译的,不知你的为什么通不过! 你的编译信息是什么?
纸飞机2017 2005-06-07
  • 打赏
  • 举报
回复
你要是用VC自己写个DLL在PB里调用就知道了。
例如对于一个返回数组指针的函数:
double* WINAPI returnlparray()
{
static double data[] = {10.05,20.1132,30.98765,3.1415926};
int i=0;
double temp;
while(temp=data[i++]);
return data;
}
PB中这样调:
SUBROUTINE CopyMemory(ref double lpDest,ulong lpSource,long nCount) LIBRARY "KERNEL32.dll" Alias for "RtlMoveMemory"
Function ulong returnlparray() library "testdll.dll"

integer i=0
ulong lul_lparray
double ldbl_data,ldbl_datarray[]

lul_lparray = returnlparray()
CopyMemory(ldbl_data,lul_lparray,8)
do while ldbl_data <> 0
i+=8
ldbl_datarray[i/8] = ldbl_data
CopyMemory(ldbl_data,lul_lparray+i,8)
loop
------------------------
并没有什么数据类型,只有1和0。
lzheng2001 2005-06-06
  • 打赏
  • 举报
回复
你想取到值,需要把参数定义为ref 型,如
Function int ReadCard(ref int Rom[], ref int Pass[], int Buiding[], int Floor[], int District[] , int Room[], int enOverride[], int FlatBit[], int TimeWindow[], int StartTime[], int EndTime[]) Library "Hotellock.dll"
在需要取值的参数前加ref
gjz_1209 2005-06-06
  • 打赏
  • 举报
回复
int Rom[2]
Rom[1] = space(10)
Rom[2] = space(10)
试一试
liubocy 2005-06-06
  • 打赏
  • 举报
回复
--------更正----------
改 Declare Global External 为:
FUNCTION INT ReadSystemPas( int Password[]) Library "Hotellock.DLL"
改为:
改 Declare Global External 为:
FUNCTION INT ReadSystemPas( ref int Password[]) Library "Hotellock.DLL"
-------------------------------------
少写了个ref
liubocy 2005-06-06
  • 打赏
  • 举报
回复
其中还有一个简单的函数:
-------------------------
short __stdcall ReadSystemPas(short *Password);
功能: 从发卡机里读取客户卡密码。
参数: *PassWord:4个short 空间。
-------------------------
Declare Global External:
FUNCTION INT ReadSystemPas( int Password[]) Library "Hotellock.DLL"
-------------------------
int re
int password[4]
re = ReadSystemPas( password )
-------------------------
上述方法程序调试没错,但password为0值。
改 Declare Global External 为:
FUNCTION INT ReadSystemPas( int Password[]) Library "Hotellock.DLL"
程序出错:
---------- Compiler: Errors
test.pbl(w_1).cb_2.clicked.49: Error C0052: Bad argument list for function: readsystempas
---------- Finished Errors

这跟标题上的问题一个样了。


princelily 2005-06-06
  • 打赏
  • 举报
回复
学识浅薄,友情+帮顶!
liubocy 2005-06-06
  • 打赏
  • 举报
回复
资料也就是一个dll和几个函数的原型。开端口、关端口和写卡都没什么问题,就是这个读卡了。
liubocy 2005-06-06
  • 打赏
  • 举报
回复
还是不行,报同样的错误。 :(
lzheng2001 2005-06-06
  • 打赏
  • 举报
回复
1.用ref是传地址,不用的话可能只是复制地址的值到另一个地址,类似copymenory, 这个没具体研究,只是估计. 你可写个PB函数测试一下,我记得,没有ref ,数组的值是不能传出来的.

2.你参数一下原函数的资料,声明时,在要输出的地方才加ref
liubocy 2005-06-06
  • 打赏
  • 举报
回复
数组本来就是地址访问,ref是参数引用。两者有什么不同吗?!
liubocy 2005-06-06
  • 打赏
  • 举报
回复
改了ref后,程序报错
---------- Compiler: Errors
test.pbl(w_1).cb_2.clicked.51: Error C0116: Reference argument type doesn't match function definition: readcard
---------- Finished Errors
用原版程序读卡是能读出来的。

680

社区成员

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

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