クラスをCヘッダーからDelphiで使用するように変換するのに問題があります。
Cヘッダーファイルの宣言のスニペットは次のようになります。
class __declspec(uuid("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"))
ISomeInterface
{
public:
virtual
BOOL
SomeBoolMethod(
VOID
) const = 0;
}
ISomeInterfaceパラメーターを受け入れるメソッドをエクスポートするDLLを作成しています。
function MyExportFunc (pSomeInterface: ISomeInterface): Cardinal; export; stdcall;
var
aBool: BOOL;
begin
aBool := pSomeInterface.SomeBoolMethod;
end;
DelphiでISomeInterfaceを次のように宣言しました。
type ISomeInterface = class
function SomeBoolMethod: BOOL; cdecl; virtual; abstract;
end;
pSomeInterface.SomeBoolMethodを呼び出すと、アクセス違反が発生します。
私は根本的に間違ったことをしていますか?
実際のCヘッダーはhttpserv.hであり、DelphiでIIS7ネイティブモジュールを実装しようとしています。
動作するいくつかのc++コードは次のようになります。
HRESULT
__stdcall
RegisterModule(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo * pModuleInfo,
IHttpServer * pHttpServer
)
{
// etc
}
デバッグすると、pModuleInfoパラメーターに__vfptrメンバーが含まれ、その下に6つのメンバー([0]から[5]の名前が付けられ、値としてアドレスがあります)が含まれていることがわかります。これは、IHttpModuleRegistrationInfoクラスの仮想メソッドへのポインターであると推測されます。
DelphiRegisterModuleのエクスポートは次のようになります。
function RegisterModule (dwServerVersion: DWORD; var pModuleInfo: Pointer; var pHttpServer: Pointer): HRESULT; export; stdcall;
begin
// etc
end;
pModuleInfoには、cppの例の__vfptrメンバーと同等のアドレスが含まれており、__ vfptrの順序がヘッダーファイルのクラス宣言と同じであると仮定して、メソッドアドレスを抽出します。
function RegisterModule (dwServerVersion: DWORD; var pModuleInfo: Pointer; var pHttpServer: Pointer): HRESULT; export; stdcall;
var
vfptr: Pointer;
ptrGetName: Pointer;
ptrGetId: Pointer;
begin
vfptr := pModuleInfo;
ptrGetName := Pointer (Pointer (Cardinal(vfptr))^);
ptrGetId := Pointer (Pointer (Cardinal(vfptr) + 4)^);
end;
呼び出すメソッドアドレスができたので、なんとかして呼び出す必要があります。私はおそらくこれをすべて間違った方法で行っています!