Я пытаюсь подключиться к плоттеру Graphtec через порт USB в Delphi. Следующий фрагмент кода C ++ предоставлен производителем:
#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 ++ в dll, который я могу вызвать из Delphi.
Вам не нужно компилировать код 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
исходит от APIENTRY
в коде C ++. Это макрос для WINAPI
который оценивает __stdcall
,
И это все, что нужно сделать. Теперь вы можете вызвать функцию из вашего кода Delphi следующим образом:
var
hWrite, hRead: THandle;
....
hWrite := GITK_OpenUsb(0, 0, FILE_FLAG_OVERLAPPED);
hRead := GITK_OpenUsb(0, 1, FILE_FLAG_OVERLAPPED);
Я использовал здесь ссылки на время загрузки. Это всегда намного удобнее и чище. И это избавляет вас от необходимости писать шаблон для загрузки библиотеки, импорта функций и проверки ошибок. Так что, если вы можете, выберите использование ссылок на время загрузки.
Там нет сомнений, больше функций для преобразования. Вы должны будете сделать их аналогичным образом. Используйте существующие ресурсы для обучения.
Windows
блок в Дельфи.Ваш фрагмент кода в 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.