大家好:我用的是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
我不明白这是为何!请高手指示!!我如何读取到其中的数据!请提供对应代码!!谢谢
顺便请问我如何给分给回答过问题的人!
解决方案 »
- 怎样在DBGridEh1中直接编辑记录
- 如何向16进制文件的指定偏移地址写入字符串?(100分)
- delphi7在台式机上可以安装、注册成功,在笔记本上可以安装、但不能注册成功,为什么?
- 求助 delphi+SQl2000
- 谁有现成的销售系统(Access)给我发一个(只要有销售和库存管理)就行(采用的就送200分)
- 一个程序员给初学编程人的建议!
- 问题还是没有解决!Delphi调用ActiveX DLL的问题,总报告找不到函数入口点!解决立即给分!!在线!
- 请问如何让程序在制定的点,停止一秒在执行.
- 存储过程的问题(oracle)!!!
- 一个frame要怎样设置才能只出现上下滚动条,而没有左右滚动条?
- ExpressQuantumGrid如何改界面,是否有皮肤。
- socket编程中如何进行重新连接?
ReadRam:=GetProcAddress(Handle,'ReadRam2k');你确信已经找到相应的函数的了吗?
Access Violation at Address 00242995 in module JBC_Attend.dll Write of address 00427510
不要放在procedure TForm1.BitBtn2Click(Sender: TObject);下面声明
放在公共声明的地方, 另外这样改, 另一个函数也一样改.
procedure TForm1.BitBtn2Click(Sender: TObject);
//功能 搜索考勤
Var
Search:TSearchar;
Handle:THandle;
AD_ID:Integer;
begin
AD_ID:=1;
Handle:=LoadLibrary('JBC_Attend.dll');
Try
@Search:=@GetProcAddress(Handle,'SearchAR');
Edit4.Text:=IntToStr(Search(AD_ID));
If (Search(AD_ID)=0) Then
Edit2.Text:='搜索考勤 1 号机器成功'
Else
Edit2.Text:='搜索考勤 1 号机器失败';
finally
FreeLibrary(Handle);
end;
End;
类声明的地方;
(@Search:=@GetProcAddress(Handle,'SearchAR')这里的@作用是确保正确的调用.
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;type
TForm1 = class(TForm)
Edit1: TEdit;
A处?
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
procedure BitBtn4Click(Sender: TObject);
procedure BitBtn5Click(Sender: TObject);
procedure BitBtn6Click(Sender: TObject);
//Function Search1(AD_ID:Integer):Integer; Stdcall;external 'JBC_Attend.dll'name 'Open_ComX'; private
{ Private declarations }
public
B处?
{ Public declarations }
end;var
Form1: TForm1;
C处?
Implementation
D处?
{$R *.dfm}procedure TForm1.BitBtn5Click(Sender: TObject);
E处?
Var
Comport:Pchar;
Band:Integer;
Begin
..
End
TForm1 = class(TForm)
Edit1: TEdit;
A处?
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
procedure BitBtn4Click(Sender: TObject);
procedure BitBtn5Click(Sender: TObject);
procedure BitBtn6Click(Sender: TObject);
//Function Search1(AD_ID:Integer):Integer; Stdcall;external 'JBC_Attend.dll'name 'Open_ComX'; private
{ Private declarations }
public
{ Public declarations }
end;Type
TSearchAR=Function(AD_ID:Integer):Integer;Stdcall;如果不行, 你把那个Dll文件发给我帮你写算了, 给我200分就OK.
我闲着没事,可能要快些。
你把它转换一下再发一次, 要不就发在网上看.
0012005091906511200003456018
0012005091907120900002142018
我的思路是:1:打开Com1口;2: 考勤机;3: 读取数据
前两步没问题,后面读取数据有问题.我的相关代码如下
private
{ Private declarations }
public { Public declarations }
end;var
Form1: TForm1;
Type TOpen_ComX=Function(Comport:Pchar;Band:Integer):Integer;Stdcall;
Type TSearchAR=Function(AD_ID:Integer):Integer;Stdcall;
Type TReadRam2k=Function(AD_ID:Integer;DataBuff:PChar;BlockFlag:Integer):Integer;Stdcall;
implementation
function Open_ComX(Comport:PChar;Band:Integer):Integer; Stdcall external 'JBC_Attend.dll'name 'Open_ComX';
function Search(AR_ID:Integer):Integer; Stdcall external 'JBC_Attend.dll'name 'SearchAR';{$R *.dfm}
procedure TForm1.BitBtn1Click(Sender: TObject);//功能:打开串口
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);
//功能: 搜索卡钟
Var
Search:TSearchar;
Handle:THandle;
AD_ID:Integer;
begin
AD_ID:=1;
Handle:=LoadLibrary('JBC_Attend.dll');
Try
Search:=GetProcAddress(Handle,'SearchAR');
Edit4.Text:=IntToStr(Search(AD_ID));
If (Search(AD_ID)=0) Then Edit2.Text:='搜索考勤 1 号机器成功'
Else Edit2.Text:='搜索考勤 1 号机器失败';
Finally
FreeLibrary(Handle);
End;
End;procedure TForm1.BitBtn3Click(Sender: TObject);
//读128条数据
Var
ReadRam:TReadRam2k;
Handle:THandle;
farfun: TFarProc;
AD_ID:Integer;
DataBuff: PChar;
BlockFlag:Integer;
begin
AD_ID:=1;
BlockFlag:=1;
Handle:=LoadLibrary('JBC_Attend.dll');
farfun:=GetProcAddress(Handle,'ReadRam2k');
If farfun<>nil then
Begin
@ReadRam:=farfun;
ReadRam(AD_ID,DataBuff,BlockFlag);
Edit3.Text:='记录读取中:'+DataBuff;
Edit4.Text:='读取状态'+IntToStr(ReadRam(AD_ID,DataBuff,BlockFlag)); Memo1.Lines.Add(DataBuff);
End;
FreeLibrary(Handle);
End;当我执行完前两步再执行读取数据时则报告如下:
Access Violation at Address 00242995 in module `JBC_Attend.dll ` Write of address 00427510
请求指教!我如何像厂商那样正常读取数据??请赋源码!!谢谢!!