У меня проблемы с преобразованием класса из заголовка C для использования в Delphi.
Фрагмент объявления в заголовочном файле C выглядит следующим образом:
class __declspec(uuid("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"))
ISomeInterface
{
public:
virtual
BOOL
SomeBoolMethod(
VOID
) const = 0;
}
Я пишу DLL, которая экспортирует метод, который принимает параметр ISomeInterface, например,
function MyExportFunc (pSomeInterface: ISomeInterface): Cardinal; export; stdcall;
var
aBool: BOOL;
begin
aBool := pSomeInterface.SomeBoolMethod;
end;
Я объявил ISomeInterface в Delphi следующим образом:
type ISomeInterface = class
function SomeBoolMethod: BOOL; cdecl; virtual; abstract;
end;
Вызов pSomeInterface.SomeBoolMethod приводит к нарушению доступа.
Я делаю что-то в корне неправильно?
Фактический заголовок C - httpserv.h, и я пытаюсь реализовать собственный модуль IIS7 в Delphi.
Некоторый код на С ++, который работает, выглядит следующим образом:
HRESULT
__stdcall
RegisterModule(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo * pModuleInfo,
IHttpServer * pHttpServer
)
{
// etc
}
При отладке я вижу, что параметр pModuleInfo содержит член __vfptr, который содержит 6 членов (с именами от [0] до [5] и имеют адреса в качестве значений), которые, как я вывел, являются указателями на виртуальные методы в классе IHttpModuleRegistrationInfo.
Экспорт в Delphi RegisterModule теперь выглядит следующим образом:
function RegisterModule (dwServerVersion: DWORD; var pModuleInfo: Pointer; var pHttpServer: Pointer): HRESULT; export; stdcall;
begin
// etc
end;
pModuleInfo содержит эквивалентный адрес члену __vfptr в примере cpp, и, предполагая, что порядок в __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;
Теперь у меня есть адрес метода для вызова, так что теперь мне просто нужно как-то его вызвать. Я, наверное, все об этом пошла не так!