Вызывать функции dll только указателем

Я пытаюсь использовать dll openVR из delphi. Тем не менее, эта DLL получила только ограниченную функцию, экспортированную, многие функции остаются внутри интерфейсов.

так как некоторые образцы для использования openVR, поэтому я взгляну на гр версии заголовка и C # версии заголовок , чтобы увидеть , как они делают это.

Я не получаю знания из заголовка c, а в заголовке c #, я замечаю, что они используют некоторую структуру (например, интерфейс в delphi) для хранения таблицы функций и имеют класс (например, класс реализации в delphi) для этой структуры , внутри класса существует функция create, которая, похоже, взламывает указатель на все эти функции.

IVRSystem FnTable;
internal CVRSystem(IntPtr pInterface)
{
    FnTable = (IVRSystem)Marshal.PtrToStructure(pInterface, typeof(IVRSystem));
}

pInterfaceУказатель дан в большом классе , который содержит набор класса реализации.

public CVRSystem VRSystem()
{
    CheckClear();
    if (m_pVRSystem == null)
    {
        var eError = EVRInitError.None;
        var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRSystem_Version, ref eError);
        if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
            m_pVRSystem = new CVRSystem(pInterface);
    }
    return m_pVRSystem;
}

где OpenVRInterop.GetGenericInterface- одна из экспортируемых функций dll.

Поэтому моя проблема:

(1) может ли delphi сделать что-то вроде того, что делает C #? похоже, он вызывает эти функции только с помощью необработанного указателя (адрес? offset?). Я искал delphi-дело с dll, только для двух способов (статический и динамический) оба требуют названия функций.

function someFunction(a : integer) :integer; stdcall; external a€™someDll.dlla€™;

dllHandle := LoadLibrary(a€™someDll.dlla€™);
@someFunction := GetProcAddress(dllHandle,'someFunction');

(2) Как загружается библиотека c? Я не нашел там связанного кода.

c#,delphi,dll,delphi-xe2,openvr,

1

Ответов: 1


1

Благодаря совету Реми, я думаю, я разработал для этого решение.

Я переводил заголовок 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 как таблицу функций, интересно, будет ли более сложный способ взломать таблицы виртуальных методов.

C #, Delphi, DLL, Дельфы-XE2, openvr,
Похожие вопросы