大家好:我用的是Delphi 7.公司有一考勤机器,厂商提供有考勤机Dll文件.
我需要调用Dll文件中对应的函数读取其中的值.其中Dll文件说明如下:JBC2900E.dll函数说明
注:所有的AR_ID变量代表卡钟地址编号.JBC2900E型地址编号为1-128.
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long Open_ComX(char * ComPort,long Baud);
功能:打开串口
参数: ComPort
端口号 如'COM1' `COM2'
Baud 波特率 9600
回车:
0 成功 非0失败
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long Close_ComX();
功能:关闭串口
回车:
0 成功 非0失败
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long SearchAR(long AR_ID);
功能:搜索卡钟
回车:0 存在 非0 不存在
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long SetARAdress(long AR_ID,long Old_AR_ID);
功能:重新设置卡钟地址编号.
参数: AR_ID
新的卡钟地址编号.
Old_AR_ID
以前的卡钟地址编号.
回车:
0 成功 非0失败
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long ReadRam2k(long AR_ID,char *DataBuff,long BlockFlag);
功能:读128条数据
参数:
DataBuff
数据从此参数回车.
BlockFlag
块标志.
回车:1 数据未完并请求下一块. 0数据完成.
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long ClearRam(long AR_ID);
功能:清除卡钟数据.
回车:
0 成功 非0失败
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport) __stdcall
long GetRecordNumber(long AR_ID,char *RecordNumber,char *LoginNumber);
功能:给出卡钟内的记录数.
参数
RecordNumber 当前卡钟内的数据记录数.
LoginNumber 当前卡钟内已注册卡号数.
回车:
0 成功 非0失败
--------------------------------------------------------------------------------还有一些,省略掉了.
--------------------------------------------------------------------------------
我用 Open_ComX函数打开Com1口,SearchAR搜索1号考勤卡机均成功.但用ReadRam2k函数读取其中数据时报错,相关程序代码如下:procedure TForm1.BitBtn1Click(Sender: TObject);
Type TOpen_ComX=Function(Comport:Pchar;Band:Integer):Integer;Stdcall;
//功能:打开串口
Var
Open_ComX:TOpen_ComX;
Handle:THandle;
Comport:Pchar;
Band:Integer;
begin
Comport:='COM1';//设置Com1口
Band:=9600; //设置速率
Handle:=LoadLibrary('JBC_Attend.dll');
Open_ComX:=GetProcAddress(Handle,'Open_ComX');
If Open_ComX(Comport,Band)=0 Then Edit1.Text:='Com1 口开启成功'
Else Edit1.Text:='Com1 口开启失败';
FreeLibrary(Handle);
end;procedure TForm1.BitBtn2Click(Sender: TObject);
//功能 搜索考勤
Type TSearchAR=Function(AD_ID:Integer):Integer;Stdcall;
Var
Search:TSearchar;
Handle:THandle;
AD_ID:Integer;
begin
AD_ID:=1;
Handle:=LoadLibrary('JBC_Attend.dll');
Search:=GetProcAddress(Handle,'SearchAR');
Edit4.Text:=IntToStr(Search(AD_ID));
If (Search(AD_ID)=0) Then Edit2.Text:='搜索考勤 1 号机器成功'
Else Edit2.Text:='搜索考勤 1 号机器失败';
FreeLibrary(Handle);
End;procedure TForm1.BitBtn3Click(Sender: TObject);
//读取数据
Type TReadRam2k=Function(AD_ID:Integer;DataBuff:PChar;BlockFlag:Integer):Integer;Stdcall;
Var
ReadRam:TReadRam2k;
Handle:THandle;
AD_ID:Integer;
DataBuff:PChar;
BlockFlag:Integer;
begin
AD_ID:=1;
DataBuff:='';
BlockFlag:=1;
Handle:=LoadLibrary('JBC_Attend.dll');
ReadRam:=GetProcAddress(Handle,'ReadRam2k');
ReadRam(AD_ID,DataBuff,BlockFlag);
Memo1.Lines.Add(DataBuff);
FreeLibrary(Handle);
End;
我先将Com1口打开,然后搜索考勤,当我进行资料读取,时报错,如下
Access Violation at Address 00242995 in module JBC_Attend.dll Write of address 00427510
我不明白这是为何!请高手指示!!我如何读取到其中的数据!请提供对应代码!!谢谢
顺便请问我如何给分给回答过问题的人!
我需要调用Dll文件中对应的函数读取其中的值.其中Dll文件说明如下:JBC2900E.dll函数说明
注:所有的AR_ID变量代表卡钟地址编号.JBC2900E型地址编号为1-128.
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long Open_ComX(char * ComPort,long Baud);
功能:打开串口
参数: ComPort
端口号 如'COM1' `COM2'
Baud 波特率 9600
回车:
0 成功 非0失败
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long Close_ComX();
功能:关闭串口
回车:
0 成功 非0失败
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long SearchAR(long AR_ID);
功能:搜索卡钟
回车:0 存在 非0 不存在
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long SetARAdress(long AR_ID,long Old_AR_ID);
功能:重新设置卡钟地址编号.
参数: AR_ID
新的卡钟地址编号.
Old_AR_ID
以前的卡钟地址编号.
回车:
0 成功 非0失败
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long ReadRam2k(long AR_ID,char *DataBuff,long BlockFlag);
功能:读128条数据
参数:
DataBuff
数据从此参数回车.
BlockFlag
块标志.
回车:1 数据未完并请求下一块. 0数据完成.
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport ) __stdcall
long ClearRam(long AR_ID);
功能:清除卡钟数据.
回车:
0 成功 非0失败
--------------------------------------------------------------------------------
extern "C" __declspec(dllimport) __stdcall
long GetRecordNumber(long AR_ID,char *RecordNumber,char *LoginNumber);
功能:给出卡钟内的记录数.
参数
RecordNumber 当前卡钟内的数据记录数.
LoginNumber 当前卡钟内已注册卡号数.
回车:
0 成功 非0失败
--------------------------------------------------------------------------------还有一些,省略掉了.
--------------------------------------------------------------------------------
我用 Open_ComX函数打开Com1口,SearchAR搜索1号考勤卡机均成功.但用ReadRam2k函数读取其中数据时报错,相关程序代码如下:procedure TForm1.BitBtn1Click(Sender: TObject);
Type TOpen_ComX=Function(Comport:Pchar;Band:Integer):Integer;Stdcall;
//功能:打开串口
Var
Open_ComX:TOpen_ComX;
Handle:THandle;
Comport:Pchar;
Band:Integer;
begin
Comport:='COM1';//设置Com1口
Band:=9600; //设置速率
Handle:=LoadLibrary('JBC_Attend.dll');
Open_ComX:=GetProcAddress(Handle,'Open_ComX');
If Open_ComX(Comport,Band)=0 Then Edit1.Text:='Com1 口开启成功'
Else Edit1.Text:='Com1 口开启失败';
FreeLibrary(Handle);
end;procedure TForm1.BitBtn2Click(Sender: TObject);
//功能 搜索考勤
Type TSearchAR=Function(AD_ID:Integer):Integer;Stdcall;
Var
Search:TSearchar;
Handle:THandle;
AD_ID:Integer;
begin
AD_ID:=1;
Handle:=LoadLibrary('JBC_Attend.dll');
Search:=GetProcAddress(Handle,'SearchAR');
Edit4.Text:=IntToStr(Search(AD_ID));
If (Search(AD_ID)=0) Then Edit2.Text:='搜索考勤 1 号机器成功'
Else Edit2.Text:='搜索考勤 1 号机器失败';
FreeLibrary(Handle);
End;procedure TForm1.BitBtn3Click(Sender: TObject);
//读取数据
Type TReadRam2k=Function(AD_ID:Integer;DataBuff:PChar;BlockFlag:Integer):Integer;Stdcall;
Var
ReadRam:TReadRam2k;
Handle:THandle;
AD_ID:Integer;
DataBuff:PChar;
BlockFlag:Integer;
begin
AD_ID:=1;
DataBuff:='';
BlockFlag:=1;
Handle:=LoadLibrary('JBC_Attend.dll');
ReadRam:=GetProcAddress(Handle,'ReadRam2k');
ReadRam(AD_ID,DataBuff,BlockFlag);
Memo1.Lines.Add(DataBuff);
FreeLibrary(Handle);
End;
我先将Com1口打开,然后搜索考勤,当我进行资料读取,时报错,如下
Access Violation at Address 00242995 in module JBC_Attend.dll Write of address 00427510
我不明白这是为何!请高手指示!!我如何读取到其中的数据!请提供对应代码!!谢谢
顺便请问我如何给分给回答过问题的人!
解决方案 »
- 求助,DELPHI PANEL条件变色!
- DBgridEh里面如何使用OnDrawColumnCell事件
- 怎样使窗体既是borderstytle=sizeable,又不显示标题栏??(自己模拟)
- Tserversocket问题?如果多个客户端同时向服务器端发送数据,用非阻塞型么?要自己写多线程么?
- 救命!help(项目文件出错,如何补救?)
- 窗体里面有多个各种各样的组件,而且都是隐藏的。怎么把其中Name为MyEdit组件显示出来?
- 急求五子棋的估价函数与搜索算法
- SOS,动态查询?
- 各位大哥,帮帮小弟我了!非常急!!!
- 各位,还是老弟有问题,关于DBGrid的问题,我快气死了。
- 怎样共享ADOConnection
- 服务器运行时报错“由于系统缓冲区空间不足或列队已满,不能执行套接字上的操作。” 是什么原因
如何用Delphi读取dll文件中函数传回的值!!
把delphi中的函数定义后的stdcall换成cdecl就可以了。
有问题和我联系。[email protected]
具体情况不是很清楚,但我想是不是应该在程序一开始时就用 Loadlibrar()加载动态库,
而在整个程序关闭时,在用FreeLibrary()去释放动态库.可以试一下
extern "C" __declspec(dllimport ) __stdcall
long ReadRam2k(long AR_ID,char *DataBuff,long BlockFlag);
为例Delphi 中声明为
function ReadRam2k(AR_ID: Longint, DataBuff: PChar; BlockFlag: Longint): Longint; stdcall; external 'JBC2900E.dll';调用例子:
var
arrBuff: array[0..1024] of Char;
intSize: Integer;
begin
// FAR_ID 为卡钟 ID
intSize := ReadRam2k(FAR_ID, arrBuff, 1024);
arrBuff[intSize] := #0;// arrBuff 就是读到的数据
// ??? ... ...
end;动态库最好使用静态加载, 你的程序中每次调用一个函数就加载和释放动态库, 所以肯定会出问题, 因为重新加载时, 数据已经重新初始化了.