开发者

Crash when C++ program calls Delphi DLL function

开发者 https://www.devze.com 2023-01-30 17:01 出处:网络
I have an abstract class in a C++ program that looks like class Interface { virtual void blah() = 0; virtual intasdf() = 0;

I have an abstract class in a C++ program that looks like

class Interface {
    virtual void blah() = 0;
    virtual int  asdf() = 0;
};

and that C++ program allows you to load DLLs with LoadLibrary. When you load a DLL, it calls a function in the DLL called Setup with GetProcAddress, passing a pointer to a subclass of Interf开发者_如何学Goace as a parameter.

I have a Delphi DLL mimics that class and exposes the Setup function like this:

type 
Interface = class abstract
    procedure blah(); virtual; abstract;
    function asdf() : Integer; virtual; abstract;
end;

function Setup(I : Interface) : Integer; export; cdecl;
begin
    Result := 0;
end

exports Setup;

But when the program calls the function, it crashes. If I change the function Setup to this:

function Setup(I : Pointer) : Integer; export; cdecl;

It works fine and doesn't crash, but of course I can't just leave it like that, I need to be able to use the class. Can someone tell me what I'm doing wrong?


I don't know about C++, but Delphi interfaces are automatically reference counted (via IUnknown). Looks like your interface has been destroyed already by the time you try to use it.

Edit: Sorry, I was confused: you're not using interfaces.

Delphi and C++ classes aren't compatible, so I don't think this is going to work. You'd have to change the class to a COM interface or a record of function pointers. If you don't have control over the C++ side you're out of luck I'm afraid.


If your C++ code really is as you say it is, you need to determine what calling convention it's using. Is it definitely using the C calling convention? What is it compiled with, and what flags for calling convention?

Your Interface class needs to include the calling convention too, something like:

Interface = class abstract
  procedure blah(); cdecl; virtual; abstract;
  function asdf() : Integer; cdecl; virtual; abstract;
end;

If the calling convention used by C++ is something like MSVC's fastcall, there's no direct equivalent in Delphi. What you could do in that case is write a proxy DLL in MSVC that converts the interface from MSVC fastcall to cdecl or similar.


You could see http://rvelthuis.de/articles/articles-cppobjs.html

But yes, using C++ in Delphi is not an easy thing... and not suitable.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号