我正在尝试通过Delphi中的USB端口连接到Graphtec绘图仪。以下是C ++代码的snipet由制造商提供:
#include <windows.h>
#include <stdio.h>
typedef HANDLE (APIENTRY *PROC_GITK_OPENUSB)(int, int, DWORD);
int main(int argc, char* argv[])
{
HMODULE hUsbLib = LoadLibrary("GITKUSBP.DLL");
PROC_GETK_OPENUSB lpfnGITK_OpenUsb = (PROC_GITK_OPENUSB)GetProcAddress(hUsbLib, "GITK_OpenUsb");
HANDLE hWrite = (lpgnGITK_OpenUsb)(0, 0, FILE_FLAG_OVERLAPPED);
HANDLE hRead = (lpgnGITK_OpenUsb)(0, 1, FILE_FLAG_OVERLAPPED);
OVERLAPPED WriteEvt, ReadEvt;
}
当然还有更多内容,但这似乎是关键代码。在Delphi中,我尝试翻译并不成功。我要么需要一些翻译方面的专业知识,要么将C ++代码转换成我可以从Delphi调用的dll的一些指导。
答案 0 :(得分:5)
您无需将C ++代码编译为DLL。您已经有一个包含代码的DLL - GITKUSBP.DLL。您没有的是从Delphi代码链接到它的方法。
从C ++开始,您通常使用头文件(.h)和导入库(.lib)进行链接。虽然此处的示例使用运行时链接,但实际上,它实现得很差。它根本不执行任何错误检查。我不认为C ++代码是一个很好的例子。
从Delphi您需要将头文件转换为Pascal。它可能看起来像这样:
function GITK_OpenUsb(
param1: Integer;
param2: Integer;
param3: DWORD
): THandle; stdcall; external 'GITKUSBP.DLL';
您可以从库文档中找到更有意义的参数名称。
stdcall
的调用约定来自C ++代码中的APIENTRY
。这是WINAPI
的宏,其值为__stdcall
。
这就是它的全部内容。您现在可以从Delphi代码中调用该函数,如下所示:
var
hWrite, hRead: THandle;
....
hWrite := GITK_OpenUsb(0, 0, FILE_FLAG_OVERLAPPED);
hRead := GITK_OpenUsb(0, 1, FILE_FLAG_OVERLAPPED);
我在这里使用加载时间链接。这总是更方便,更清洁。并且它使您无需编写样板来加载库,导入函数以及执行错误检查。因此,如果可以,请选择使用加载时间链接。
毫无疑问,有更多功能需要转换。你必须以类似的方式做到这一点。请利用现有资源进行学习。
Windows
单元。答案 1 :(得分:3)
Delphi中的代码片段是:
更新:我改进了代码片段来处理DLL加载错误:
uses Windows;
type
TPROC_GITK_OPENUSB = function(A1, A2: Integer; A3: DWORD): THandle; stdcall;
procedure main;
var
hUsbLib: THandle;
fnGITK_OpenUsb: TPROC_GITK_OPENUSB;
hWrite, hRead: THandle;
WriteEvt, ReadEvt: OVERLAPPED;
begin
hUsbLib:= LoadLibrary('GITKUSBP.DLL');
if (hUsbLib <> 0) then begin
@fnGITK_OpenUsb:= GetProcAddress(hUsbLib, 'GITK_OpenUsb');
if @fnGITK_OpenUsb <> nil then begin
hWrite:= fnGITK_OpenUsb(0, 0, FILE_FLAG_OVERLAPPED);
hRead:= fnGITK_OpenUsb(0, 1, FILE_FLAG_OVERLAPPED);
// ....
end;
FreeLibrary(hUsbLib);
end;
end;
begin
main;
end.