繁体   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