2013-12-17 61 views
1

我試圖通過Delphi中的USB端口連接到Graphtec繪圖儀。的C++代碼下面snipet是由製造商提供:將C++轉換爲Delphi,或者轉換爲dll

#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; 
} 

還有更多的它,當然,但這似乎是至關重要的代碼。在德爾福,我沒有成功嘗試翻譯。我需要一些翻譯方面的專業知識,或者將C++代碼轉換爲我可以從Delphi調用的dll的一些指導。

+1

試圖h2pas的類型的轉換? –

回答

5

您不需要將C++代碼編譯爲DLL。你已經有了一個包含代碼的DLL - GITKUSBP.DLL。你沒有的是從你的Delphi代碼鏈接到它的方法。

從C++中,您通常使用頭文件(.h)和導入庫(.lib)進行鏈接。雖然這裏的示例使用了運行時鏈接,但實際上它實現的很糟糕。它根本不執行錯誤檢查。我不會把那些C++代碼作爲一個很好的例子。

從德爾福你需要翻譯頭文件到帕斯卡。它可能如下所示:

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); 

我用負載時鏈接在這裏。這總是更方便,更清潔。它可以免除您編寫樣板文件以加載庫,導入函數和執行錯誤檢查的需要。所以,如果可以的話,選擇使用加載時間鏈接。

毫無疑問,有更多的功能可以轉換。你必須以類似的方式做它們。請利用現有資源進行學習。

  • 您當然必須閱讀德爾福文檔:Importing Functions from Libraries
  • 頭文件翻譯的一個重要來源是Delphi中的Windows單元。
  • JEDI項目有很多標題翻譯。
  • 當然在這裏Stack Overflow是關於這個主題的大量問題。
+0

哇!謝謝大衛,快速而詳細的回覆。你搖滾!我會處理你的建議。 – user2618256

3

井德爾福代碼段爲:


更新:我改進了片段處理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. 
+1

這是一個很好的翻譯,但它的缺點是你也翻譯了錯誤處理的缺失!;-) –

+1

我只回答問題:)。這段代碼本身也沒有意義,只是作爲更大代碼的一部分。 – kludg

+1

那麼,提醒提問者不會有什麼傷害,特別是他們似乎可能不知道這樣的問題。如果你添加了這樣的警告,我不會因爲評論而讓你的回答變得混亂。 –