一个关于dll的简单问题,请指教(150)

L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
有一个简单问题,我现在有一个dll的vc创建新应用程序的说明,delphi中如何调用?请指教。应用说明如下VC 创建一个新应用程序的过程:1.VC6 中创建一个对话框应用程序。将Demo 目录下的三个文件abcd_DLL.h/lib/dll 复制过来。2.在应用程序的CPP 文件中添加DLL引用声明:#include "abcd_dll.h"#pragma comment(lib," abcd_dll.lib")3.在应用程序的CPP 文件中的初始化部分,添加一个初始化函数:abcd_Init();4.在应用程序的CPP 文件中的任何地方:需要读取端口状态,则调用函数abcd_Read();需要控制端口状态,则调用函数abcd_Write();由于自己在dll没啥经验。请教在delphi中如何调用?
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
主要是如何调用abcd_Read()和abcd_Write(),难者不会,会者不难
 
D

dark_power

Unregistered / Unconfirmed
GUEST, unregistred user!
我只看完前十一个字就返回了。
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
你也别生气,前几年,像我今天发的帖子,有时几分钟就有人解答。自己开始看书吧
 
D

dark_power

Unregistered / Unconfirmed
GUEST, unregistred user!
其实我并不生气,我只是为你悲哀。你这前十一个字是提问的败笔。就好像你问别人在delphi里类怎么声明,末尾加一句“Delphi真垃圾这年头居然还有用的”你说有人会回答你么?Delphi里用动态链接库和C中类似。要么静态引入,要么动态加载,都是这么干的。无非你把.h文件里的内容转换成Delphi(Pascal)的。静态引入使用function dllxxxABC(para1: type1; para2: type2;...):retunType; stdcall; external 'xxx.dll';动态加载就不用我说了吧?都一样的调用格式。注意类型的兼容性和区别就是了。
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
批评的对。我只是感慨,今天虽然放假,在线富翁寥寥无几,以前可是几十上百。谢谢您的指点
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
//abcd_DLL.h文件#include <windows.h>extern "C" __declspec(dllimport) void abcd_Init();extern "C" __declspec(dllimport) void abcd_Read(BYTE *data1,BYTE *data2,BYTE *data3);extern "C" __declspec(dllimport) void abcd_Write(BYTE data1,BYTE data2,BYTE data3);半天没看懂
 
D

dark_power

Unregistered / Unconfirmed
GUEST, unregistred user!
const ABCDdll = 'abcd_DLL.dll';procedure abcd_Init; cdecl; external ABCDdll;procedure abcd_Read(pData1, pData2, pData3: PByte); cdecl; external ABCDdll;procedure abcd_Write(pData1, pData2, pData3: PByte); cdecl; external ABCDdll;你这么声明试试。其实,你完全可以把这些声明放在一个Unit中,然后uses它,个人觉得这样比较整洁。
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
谢谢,不过没通过.我刚才找到了vb代码,已编辑通过,贴出来供各位分析,看如何改成delphi:Option Explicit'以下是ABCD_DLL的函数定义Private Declare Sub ABCD_Init Lib "ABCD_dll.dll" ()Private Declare Function ABCD_Read Lib "ABCD_dll.dll" () As LongPrivate Declare Sub ABCD_Write Lib "ABCD_dll.dll" (ByVal port As Long)Private Sub Command1_Click() ABCD_Write (Val(Text1.Text))End SubPrivate Sub Command2_Click() Text1.Text = ABCD_ReadEnd SubPrivate Sub Form_Load() ABCD_InitEnd Sub
 
V

Vsun

Unregistered / Unconfirmed
GUEST, unregistred user!
申明的过程与函数名必须与dll中导出的一致,并且区分大小写的。如果你不知道你的dll导出的函数名字可以用eXeScope查看此dll得到导出的正确函数名。按照你给出的C的例子,改出如下代码:procedure abcd_Init(); cdecl; external 'ABCD_dll.dll';function abcd_Read(var data1, data2, data3: Pbyte): Longint; cdecl; external 'ABCD_dll.dll';procedure abcd_Write(var data1, data2, data3: Pbyte); cdecl; external 'ABCD_dll.dll';按照你给出的VB例子,改成了如下代码:procedure ABCD_Init(); cdecl; external 'ABCD_dll.dll';function ABCD_Read(): Longint; cdecl; external 'ABCD_dll.dll';procedure ABCD_Write(var port: Longint); cdecl; external 'ABCD_dll.dll';
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
非常感谢各位!由于咱是业余爱好,只能下午回家实验,我看应该差不多了!弱弱的再问一下: 1、我知道函数function ABCD_Read(pData1, pData2, pData3: PByte) :Cardinal; cdecl; external ABCDdll; 可以加到implementation以下任一处地方; 2、procedure ABCD_Write... 和procedure ABCD_Init... 过程内容加入方法如上;而上边的声明,最好加在什么地方? 3、const ABCDdll = 'abcd_DLL.dll'; 还需要加吗,加到什么位置最好?
 
V

Vsun

Unregistered / Unconfirmed
GUEST, unregistred user!
我贴的代码放在implementation后即可,我贴的代码不需要 abcddll='abcd_dll.dll'这一行
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
to Vsun按你说的位置,两种都试了,提示如下[Error] Unit1.pas(56): Types of actual and formal var parameters must be identical
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
谢谢dark_power和Vsun,也许问题出在别处。我将0写入,显示成功,但读老是出错。用vb编译的程序读,发现数字变成16145628,而且无论写入什么信息,用vb编译的程序读都是16145628。
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
data1:=PChar(edit1.text) ; //data2:=nil; data3:=nil; abcd_Write(Pbyte(data1));无论写入什么信息,用vb编译的程序读都是15621332。 这里问题可能出在Pbyte参数上
 
B

bahamut8348

Unregistered / Unconfirmed
GUEST, unregistred user!
首先:搞清楚函数名,注意DLL函数名大小写敏感的。第二:搞清楚参数,var关键字不能乱加的,看上面有几位的DELPHI翻译和那个C的头文件明显的就不一样,按照LZ给的头文件内容:extern "C" __declspec(dllimport) void abcd_Init();extern "C" __declspec(dllimport) void abcd_Read(BYTE *data1,BYTE *data2,BYTE *data3);extern "C" __declspec(dllimport) void abcd_Write(BYTE data1,BYTE data2,BYTE data3);硬翻译的话可以写成:procedure abcd_Init; cdecl; external 'abcd_DLL.dll' name 'abcd_Init';procedure abcd_Read(Data1, Data2, Data3: PByte); cdecl; external 'abcd_DLL.dll' name 'abcd_Read';procedure abcd_Write(Data1, Data2, Data3: Byte); cdecl; external 'abcd_DLL.dll' name 'abcd_Write';LZ可以自己对照一下看看(注意看参数部分)下面的那个ABCD_Write(pbyte(data1))那句,不知道你函数原形需要的参数到底是什么东西,如果是要求一个pbyte类型就没关系,如果不是的话,你这样是直接传了地址进去,当然只要指针指向的地址不变就不会有变化了,你可以改成abcd_write(pbyte(data1)^);看看好了。。看你VB的函数原形,参数应该是一个数值型,而不是指针,你这么传肯定是问题一堆,还是那句话,var关键字不要乱加。。要先搞清楚函数参数的意义再说。。不过,这函数实在是太那什么了。。。要求的参数是一个缓冲区,但是又不带一个长度参数。太让人费解了。。。
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
abcd_Write虽有问题还可用,abcd_Read函数一用就报错。
 
B

bahamut8348

Unregistered / Unconfirmed
GUEST, unregistred user!
你贴的东西太少了,出错,出什么错呢?我给你一个例子你自己看看吧。。testdll.cpp的内容:BOOL WINAPI Initimize( LPSTR lpFileName ){ hFile = ::CreateFile( lpFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); return ( INVALID_HANDLE_VALUE != hFile );}DWORD WINAPI ReadBuffer( BYTE &lpBuffer, DWORD dwBufferSize ){ if ( INVALID_HANDLE_VALUE == hFile ) return 0; if ( ::SetFilePointer( hFile, FILE_BEGIN, NULL, 0 ) == 0xffffffff && ::GetLastError() != ERROR_SUCCESS ) return 0; DWORD dwReadBytes = 0; if ( ::ReadFile( hFile, (void *)&lpBuffer, dwBufferSize, &dwReadBytes, NULL ) ) { return dwReadBytes; } else return 0;}DWORD WINAPI WriteBuffer( BYTE *lpBuffer, DWORD dwBufferSize ){ if ( INVALID_HANDLE_VALUE == hFile ) return 0; if ( ::SetFilePointer( hFile, FILE_BEGIN, NULL, 0 ) == 0xffffffff && ::GetLastError() != ERROR_SUCCESS ) return 0; DWORD dwWriteBytes = 0; if ( ::WriteFile( hFile, lpBuffer, dwBufferSize, &dwWriteBytes, NULL ) ) return dwWriteBytes; else return 0;}BOOL WINAPI UnInitimize( void ){ if ( INVALID_HANDLE_VALUE == hFile ) return FALSE; if ( ::CloseHandle( hFile ) ) { hFile = INVALID_HANDLE_VALUE; return TRUE; } else return FALSE;}调用方内容:unit Main;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;const TestDll = 'TestDll.dll';function Initimize(lpFileName: PAnsiChar): BOOL; stdcall; external TestDll name 'Initimize';function ReadBuffer(var lpBuffer; dwBufferSize: DWORD): DWORD; stdcall; external TestDll name 'ReadBuffer';function WriteBuffer(const lpBuffer; dwBufferSize: DWORD): DWORD; stdcall; external TestDll name 'WriteBuffer';function UnInitimize(): BOOL stdcall; external TestDll name 'UnInitimize';implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);begin Initimize('C:/1.txt');end;procedure TForm1.FormDestroy(Sender: TObject);begin UnInitimize;end;procedure TForm1.Button1Click(Sender: TObject); var s: AnsiString;begin s:= Edit1.Text; WriteBuffer(s[1], Length(s));end;procedure TForm1.Button2Click(Sender: TObject); var s: AnsiString;begin SetLength(s, MAX_PATH); ReadBuffer(s[1], MAX_PATH); Edit1.Text:= s;end;end.
 
D

dorry

Unregistered / Unconfirmed
GUEST, unregistred user!
接口这样声明:注意大小写!unit DllInterface;interfaceconst EasyDLL='EasyUSB_DLL.dll'; procedure EasyUSB_Init(); cdecl; procedure EasyUSB_Read(Data1,data2,data3:pbyte);cdecl; procedure EasyUSB_Write(Data1,data2,data3:Word);cdecl;implementation procedure EasyUSB_Init; external EasyDLL Name 'EasyUSB_Init';//注意大小写 procedure EasyUSB_Read; external EasyDLL Name 'EasyUSB_Read';//注意大小写 procedure EasyUSB_Write; external EasyDLL Name 'EasyUSB_Write';//注意大小写end.这样调用即可。unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementationuses DllInterface;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);begin try EasyUSB_Init; except ShowMessage('未找到设备!'); end;end;procedure TForm1.Button2Click(Sender: TObject);var D1,D2,D3:array[0..10] of Byte;begin EasyUSB_Read(@D1[0],@D2[0],@D3[0]);end;试一试!
 
L

laowt

Unregistered / Unconfirmed
GUEST, unregistred user!
多人接受答案了。
 
顶部