Благодаря совету Реми, я думаю, я разработал для этого решение.
Я переводил заголовок C # в delphi, и теперь он отлично работает.
Я буду использовать VRSystem в качестве примера.
Во-первых, нам нужно некоторое базовое перечисление, const, struct translate.
enum необходимо использовать тег Z4, чтобы размер совпадал с c перечислением типа.
{$Z4}
ETrackingResult = (
ETrackingResult_Uninitialized = 1,
ETrackingResult_Calibrating_InProgress = 100,
ETrackingResult_Calibrating_OutOfRange = 101,
ETrackingResult_Running_OK = 200,
ETrackingResult_Running_OutOfRange = 201
);
для структуры, запись идеально подходит.
TrackedDevicePose_t = record
mDeviceToAbsoluteTracking : HmdMatrix34_t;
vVelocity : HmdVector3_t;
vAngularVelocity : HmdVector3_t;
eTrackingResult : ETrackingResult;
bPoseIsValid : boolean;
bDeviceIsConnected : boolean;
end;
и тогда нам нужно умерить функции делегата для каждой функции внутри интерфейса, подобного этому.
_GetRecommendedRenderTargetSize = procedure(var pnWidth : uint32; var pnHeight : uint32); stdcall;
_GetProjectionMatrix = function(eEye : EVREye; fNearZ : single; fFarZ : single; eProjType : EGraphicsAPIConvention) : HmdMatrix44_t; stdcall;
...
_AcknowledgeQuit_UserPrompt = procedure(); stdcall;
и структуру для их хранения, но на этот раз нам нужен идеальный размер, поэтому нам нужна упакованная запись
PIVRSystem = ^IVRSystem;
IVRSystem = packed record
GetRecommendedRenderTargetSize : _GetRecommendedRenderTargetSize;
GetProjectionMatrix : _GetProjectionMatrix;
....
AcknowledgeQuit_UserPrompt : _AcknowledgeQuit_UserPrompt;
end;
и, наконец, класс удерживает struct и запустит эту структуру, указав на нее указатель.
CVRSystem = class
FnTable : PIVRSystem;
Constructor Create(FNPointer : IntPtr);
procedure GetRecommendedRenderTargetSize(var pnWidth : uint32; var pnHeight : uint32);
function GetProjectionMatrix(eEye : EVREye; fNearZ : single; fFarZ : single; eProjType : EGraphicsAPIConvention) : HmdMatrix44_t;
...
procedure AcknowledgeQuit_UserPrompt();
end;
поэтому теперь мы можем использовать эти функции, вызывая функцию внутри CVRSystem
которой непосредственно указывает на функцию внутриFNTable
Таким образом, мы используем struct как таблицу функций, интересно, будет ли более сложный способ взломать таблицы виртуальных методов.