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

Call Delphi CLASS exported in DLL from C++ code

本文关键字:DLL 中的 Delphi CLASS C++ 代码 调用      更新时间:2023-10-16

我在C++代码中使用Delphi class时遇到问题。 德尔福 DLL 演示,用于导出返回对象的函数。我的德尔福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("%un", errc); // it gets error 127
}
else{
    printf("success loadn");
}
   IMyObject*  objptr = pfnCreate();
   objptr->DoThis(5);
   FreeLibrary(hLib);
   int in;
   scanf_s("%i", &in);
   return 0;
 }

在这个例子中,当我尝试访问导出的函数时,我在运行时遇到错误。 错误在行: IMyObject* objptr = pfnCreate();

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

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

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

除此之外,您的德尔福代码导出PWideChar不会映射到char*。它映射到wchar_t* .

展望未来,返回PChar在这里工作正常,因为您的实现返回文本。但是更严肃的代码可能希望使用动态分配的字符串,此时您的设计是有缺陷的。

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

我预计还有其他错误,但这就是我到目前为止发现的全部。