从C ++代码调用DLL中导出的Delphi CLASS

时间:2016-02-19 15:24:43

标签: c++ class delphi dll interface

我在使用C ++代码中的delphi类时遇到问题。 delphi dll演示,导出一个返回一个对象的函数。 我的delphi Dll代码如下:

 library DelphiTest; 
 // uses part....
 type
 IMyObject = interface
   procedure DoThis( n: Integer );
   function DoThat : PWideChar;
end;
TMyObject = class(TInterfacedObject,IMyObject)
   procedure DoThis( n: Integer );
   function DoThat: PChar;
end;
// TMyObject implementation go here ...
procedure TMyObject.DoThis( n: Integer );
begin
 showmessage('you are calling the DoThis methode with '+intToStr(n) +'parameter');
end;

function TMyObject.DoThat: PChar;
begin
  showmessage('you are calling the DoThat function');
  Result := Pchar('Hello im Dothat');
end;

//导出DLL函数:

function CreateMyObject : IMyObject; stdcall;export;
var
 txt : TextFile;
begin
  AssignFile(txt,'C:\log.log');
  Reset(txt);
  Writeln(txt,'hello');
  Result := TMyObject.Create;
end;

exports  CreateMyObject;

在我的C ++项目中,我将IMyObject接口声明如下:

   class IMyObject
    {
       public:
         IMyObject();
         virtual ~IMyObject();
         virtual void DoThis(int n) = 0;
         virtual char* DoThat() = 0;
    };

我的主要功能如下:

typedef  IMyObject* (__stdcall *CreateFn)();

int main()
{
HMODULE hLib;
hLib = LoadLibrary(L"DelphiTest.dll");

assert(hLib != NULL); // pass !!
CreateFn pfnCreate;
pfnCreate = (CreateFn)GetProcAddress((HINSTANCE)hLib, "CreateMyObject");

if (pfnCreate == NULL)
{
    DWORD errc = GetLastError();
    printf("%u\n", errc); // it gets error 127

}
else{
    printf("success load\n");
}
   IMyObject*  objptr = pfnCreate();
   objptr->DoThis(5);
   FreeLibrary(hLib);
   int in;
   scanf_s("%i", &in);
   return 0;
 }

使用此示例,当我尝试访问导出的函数时,我在运行时遇到错误。错误在线: IMyObject* objptr = pfnCreate();

你能告诉我我的例子有什么问题吗? 如果可能的话,从C ++代码访问Delphi类(在DLL中)的任何工作示例。

1 个答案:

答案 0 :(得分:2)

第一个问题是调用方法的约定。 Delphi接口使用register这是Delphi特定的调用约定。例如,使用stdcall作为接口的方法。

下一个问题出在C ++中。您的C ++接口必须派生自IUnknown。此外,它不应声明构造函数或析构函数。

除此之外,您的Delphi代码导出PWideChar,但不会映射到char*。它映射到wchar_t*

展望未来,返回PChar可以正常工作,因为您的实现会返回一个文字。但更严重的代码可能会想要使用动态分配的字符串,此时您的设计存在缺陷。

请注意,您需要成为提升管理员才能在系统驱动器的根目录下创建文件。这是另一个潜在的失败点。

我希望还有其他错误,但到目前为止我发现了这些错误。