Tengo algunas DLL compiladas en MSVC++ para las que he creado interfaces COM (interfaz literaria) (clases abstractas de Delphi). Algunas de esas clases tienen métodos que necesitan punteros a los objetos. Estos métodos C++ se declaran con la convención de llamadas __thiscall (que I no puede cambiar), que es como __stdcall, excepto que este puntero se pasa en el registro ECX.Pasar una clase Delphi a una función/método C++ que espera una clase con __thiscall methods
Creo la instancia de clase en Delphi, luego la paso al método C++. Puedo establecer puntos de interrupción en Delphi y ver cómo golpea los métodos __stdcall expuestos en mi clase Delphi, pero pronto obtengo un STATUS_STACK_BUFFER_OVERRUN y la aplicación tiene que salir. ¿Es posible emular/tratar con __thiscall en el lado Delphi de las cosas? Si paso un objeto instanciado por el sistema C++, entonces todo está bien, y los métodos de ese objeto se llaman (como era de esperar), pero esto es inútil: necesito pasar objetos Delphi.
Editar 2010-04-19 18:12 Esto es lo que ocurre con más detalle: El primer método llamado (setLabel) sale sin error (aunque es un método de talón). El segundo método llamado (init), ingresa y luego muere cuando intenta leer el parámetro vol.
C++ lateral
#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 lateral
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;
que tendría la mitad espera que el uso de stdcall solo para trabajar, pero algo es echar a perder, no está seguro de lo que, tal vez algo que ver con el registro ECX que se está utilizando? La ayuda sería muy apreciada.
Editar 2010-04-19 17:42 Podría ser que el registro ECX necesita ser preservado a la entrada y una vez restaurado se cierra la función? ¿Es el este puntero requerido por C++? Probablemente estoy acaba de llegar en este momento basado en algunas búsquedas intensas de Google. I encontró something related, pero parece estar tratando con el inverso de este problema.
Usted dice que "pronto" obtiene un error STATUS_STACK_BUFFER_OVERRUN. ¿Que tan pronto? ¿Puedes publicar un código de muestra para mostrar dónde ocurre el error? ¿Sucede en todos los métodos? (¿Has probado todos los métodos?) –
@Mason, la persona que llama está poniendo argumentos 'N' en la pila, incluido' this'. El receptor solo está eliminando los argumentos 'N-1' porque cree que' this' está en el registro ECX, no en la pila. Eso lleva a un desbordamiento de pila eventualmente. –
El primer método llamado (setLabel) sale sin error (aunque es un método stub). El segundo método llamado (init), ingresa y luego muere cuando intenta leer el parámetro * vol *. – Atorian