我在将类从 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;
我在 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 类中的虚拟方法的指针。
Delphi RegisterModule 导出现在看起来像这样:
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;
我现在有了要调用的方法地址,所以现在我只需要以某种方式调用它。不过,我可能会走错路!