簡體   English   中英

如何獲取接口從C dll到Delphi?

[英]How to get interface from C dll to Delphi?

我有一個用 C 編寫的庫,我有一個 header 文件,其中包含 C 中的接口描述。DLL 有一個 function 來獲取此接口。 DELPHI申請中如何正確描述並獲取?

    using DllCallbackClassPtr = void*;
    using DllCallbackFunction = void(*)(const char *, DllCallbackClassPtr);

    #ifdef _WIN32

    #include <Windows.h>

    __interface IXeoma
    {

    public:
        enum ConnectErrorCode {
            OK = 0,
            SERVER_NOT_FOUND,
            WRONG_PASSWORD,
            UNKNOWN
        };

        // return ConnectErrorCode
        virtual int start(const char* connectionString) = 0;
        virtual bool isConnected() = 0;
        virtual void stop() = 0;

        virtual void requestData(const char* request, const char* additionalData, DllCallbackClassPtr classPtr, DllCallbackFunction callbackFunc) = 0;
        virtual const char* getRequestResult(const char* request) = 0;

        virtual void setCameraRenderHandle(const char* previewId, HWND hWnd) = 0;

    };

庫已加載,但 function 返回 nil。

    type
       IXeoma = interface
         function Start(connectionString: PChar): integer;
       end;

    type
        TCreateXeomaInterface = function() : IXeoma; stdcall;

    var
        Form1: TForm1;
        CreateXeomaInterface: TCreateXeomaInterface;

    implementation

    {$R *.dfm}

    var
        LibraryHandle: THandle;

     procedure TForm1.Button1Click(Sender: TObject);
    var
        XeomaInt: IXeoma;
        i: integer;
    begin
        LibraryHandle := LoadLibrary(PChar('D:\Projects\XeomaSDK\Win32\Debug\xeomaclientdll.dll'));
        if LibraryHandle >= 32 then
        begin
            @CreateXeomaInterface := GetProcAddress(LibraryHandle, 'createXeomaInterface');
        end;
        XeomaInt := CreateXeomaInterface();
        // Here XeomaInt = nil
    end;

Visual C++ 中的__interface擴展和 Delphi 中的interface關鍵字不是一回事,彼此不兼容。

IXeoma代碼中的IXeoma只是一個普通的class類型,不是COM接口。 但是在 Delphi 中,所有interface都派生自IUnknown ,所有class派生自TObject ,在這種情況下你都不想要。 因此,您將不得不改用普通record ,並將TCreateXeomaInterface聲明為返回指向該記錄的指針。

另外,請注意 Delphi record不能有virtual方法,但 C++ class 確實有虛擬方法,因此您將不得不手動說明 Delphi 中 C++ 類的 vtable。

嘗試這樣的事情:

type
  DllCallbackClassPtr = Pointer;
  DllCallbackFunction = procedure(Param1: PAnsiChar; Param2: DllCallbackClassPtr); cdecl;

  IXeomaPtr = ^IXeoma; 

  IXeomaVTable = record
    start: function(_Self: IXeomaPtr; connectionString: PAnsiChar): Integer; cdecl;
    isConnected: function(_Self: IXeomaPtr): Boolean; cdecl;;
    stop: procedure(_Self: IXeomaPtr); cdecl;
    requestData: procedure(_Self: IXeomaPtr; request: PAnsiChar; additionalData: PAnsiChar; classPtr: DllCallbackClassPtr; callbackFunc: DllCallbackFunction); cdecl;
    getRequestResult: function(_Self: IXeomaPtr; request: PAnsiChar): PAnsiChar; cdecl;
    setCameraRenderHandle: procedure(_Self: IXeomaPtr; previewId: PAnsiChar; hWnd: HWND); cdecl;
  end;

  ConnectErrorCode = (
    OK = 0,
    SERVER_NOT_FOUND,
    WRONG_PASSWORD,
    UNKNOWN
  ); 

  IXeoma = record
    vtable: ^IXeomaVTable:
  end;

type
  TCreateXeomaInterface = function() : IXeomaPtr; stdcall;

var
  Form1: TForm1;
  CreateXeomaInterface: TCreateXeomaInterface;

implementation

{$R *.dfm}

var
  LibraryHandle: THandle;

procedure TForm1.Button1Click(Sender: TObject);
var
  XeomaInt: IXeomaPtr;
  i: integer;
begin
  XeomaInt := nil;
  LibraryHandle := LoadLibrary('D:\Projects\XeomaSDK\Win32\Debug\xeomaclientdll.dll');
  if LibraryHandle >= 32 then
  begin
    @CreateXeomaInterface := GetProcAddress(LibraryHandle, 'createXeomaInterface');
    XeomaInt := CreateXeomaInterface();
    if XeomaInt <> nil then
      XeomaInt^.vtable^.start(XeomaInt, '123:123@localhost:8090'); 
  end;
  ...
end;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM