Как через ffi получить __uuidof для IUnknown::QueryInterface ?

Andrinall

Известный
Автор темы
678
531
Версия MoonLoader
.027.0-preview
Вопрос в названии темы.
Нужно получить IDXGIDevice, используя IDirect3DDevice9::QueryInterface (он же IUnknown::QueryInterface т.к. там наследование),
но не понятно 2 момента - как кастовать метод, а именно как обозначать первый параметр с IID... void*?
И второе - как получить этот самый REFIID (или просто IID) для первого параметра именно через код?

Lua:
local ffi = require 'ffi'
ffi.cdef[[
  struct d3ddeviceVTBL {
    // IUnknown
    void *QueryInterface;
    void *AddRef;
    void *Release;
    // ... others
  };
  struct d3ddevice { struct d3ddeviceVTBL** vtbl; };

  struct dxgideviceVTBL {
    // IDXGIObject
    void *SetPrivateData;
    void *SetPrivateDataInterface;
    void *GetPrivateData;
    void *GetParent; //HRESULT __stdcall GetParent(void*, void**);
    // ... others
  };
  struct dxgidevice { struct dxgideviceVTBL** vtbl; };
]]


-- main
local pDevice = ffi.cast("struct d3ddevice*", 0xC97C28).vtbl[0]
local pgiDevice = ffi.new("struct dxgidevice*[1]")
ffi.cast("HRESULT(__stdcall*)(void*, void**)", pDevice.QueryInterface)(--[[ типо а что тут? ]], ffi.cast('void**', pgiDevice))

UPD:
Ручное заполнение структуры GUID ни к чему положительному не привело. Возвращает ошибку E_NOINTERFACE
Lua:
ffi.cdef[[
typedef struct _GUID
{
    unsigned long  Data1; // uint64_t ?
    uint16_t Data2;
    uint16_t Data3;
    uint8_t  Data4[8];
} IID, *REFIID;
]]

-- main
local pDevice = ffi.cast("struct d3ddevice*", 0xC97C28).vtbl[0]

local pgiDevice = ffi.new("struct dxgidevice*[1]")
local iid = ffi.new('IID', { 0x54ec77fa, 0x1377, 0x44e6, { 0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c } }) -- {54ec77fa-1377-44e6-8c32-88fd5f44c84c}

local result = ffi.cast("HRESULT(__stdcall*)(REFIID, void**)", pDevice.QueryInterface)(ffi.cast('REFIID', iid), ffi.cast('void**', pgiDevice))
assert(result >= 0, 'QueryInterface returned error code: ' .. (result == -2147467262 and 'E_NOINTERFACE' or tostring(result)))
 
Последнее редактирование:
  • Нравится
Реакции: Vespan