I have some MSVC++ compiled DLL's for which I have created COM-like (lite) interfaces (abstract Delphi classes). Some of those classes have methods that need pointers to objects. These C++ methods are declared with the __thiscall calling convention (which I cannot change), which is just like __stdcall, except a this pointer is passed on the ECX register.
I create the class instance in Delphi, then pass it on to the C++ method. I can set breakpoints in Delphi and see it hitting the exposed __stdcall methods in my Delphi class, but soon I get a STATUS_STACK_BUFFER_OVERRUN and the app has to exit. Is it possible to emulate/deal with __thiscall on the Delphi side of things? If I pass an object instantiated by the C++ system then all is good, and that object's methods are called (as would be expected), but this is useless - I need to pass Delphi objects.
Edit 2010-04-19 18:12 This is what happens in more detail: The first
method called (setLabel) exits with no
error (though its a stub method). The
second method called (init), enters
then dies when it attempts to read the
vol parameter.
C++ Side
#define SHAPES_EXPORT __declspec(dllexport) // just to show the value
class SHAPES_EXPORT CBox
{
public:
virtual ~CBox() {}
virtual void init(double volume) = 0;
virtual void grow(double amount) = 0;
virtual void shrink(double amount) = 0;
virtual void setID(int ID = 0) = 0;
virtual void setLabel(const char* text) = 0;
};
Delphi Side
IBox = class
public
procedure destroyBox; virtual; stdcall; abstract;
procedure init(vol: Double); virtual; stdcall; abstract;
procedure grow(amount: Double); virtual; stdcall; abstract;
procedure shrink(amount: Double); virtual; stdcall; abstract;
procedure setID(val: Integer); virtual; stdcall; abstract;
procedure setLabel(text: PChar); virtual; stdcall; abstract;
end;
TMyBox = class(IBox)
protected
FVolume: Double;
FID: Integer;
FLabel: String; //
public
constructor Create;
destructor Destroy; override;
// BEGIN Virtual Method implementation
procedure destroyBox; override; stdcall; // empty - Dont need/want C++ to manage my Delphi objects, just call their methods
procedure init(vol: Double); override; stdcall; // FVolume := vol;
procedure grow(amount: Double); override; stdcall; // Inc(FVolume, amount);
procedure shrink(amount: Double); override; stdcall; // Dec(FVolume, amount);
procedure setID(val: Integer); override; stdcall; // FID := val;
procedure setLabel(text: PChar); override; stdcall; // Stub method; empty.
// END Virtual Method implementation
property Volume: Double read FVolume;
property ID: Integer read FID;
property Label: String read FLabel;
end;
I would have half expected using stdcall alone to work, but something is messing up, not sure what, perhaps something to do with the ECX register being used? Help would be greatly appreciated.
Edit 2010-04-19 17:42 Could it be that the ECX register needs to be
preserved on entry and restored once
the function exits? Is the this
pointer required by C++? I'm probably
just reaching at the moment based on
some intense Google searches. I
found something related, but it
seems to be dealing with the reverse
of this issue.