Методы интерфейса

Тема в разделе "WASM.BEGINNERS", создана пользователем assch, 3 окт 2023.

  1. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    разбираю ради интереса один пример на С++ с использованием интерфейса

    с последующей переброской его на рельсы - masm32

    в примере используется интерфейс - IDirect3D8

    функцией - Direct3DCreate8
    инициализируется интерфейсом переменная - p_d3d

    p_d3d = Direct3DCreate8 (D3D_SDK_VERSION);

    дальше в коде можно пользоватся методами этого интерфейса
    например

    p_d3d->GetAdapterDisplayMode (D3DADAPTER_DEFAULT, &d3ddm);

    для этого нужно только чтобы этот интерфес был обьявлен в программе

    но например я не хочу заморачиватся с обьявлением этого интерфейса
    и зная смещение в интерфейсе метода - GetAdapterDisplayMode (32)
    я например просто хочу пользоваться этими непосредственными значениями

    как синтаксически это нужно записывать

    например в лоб

    p_d3d->32 (D3DADAPTER_DEFAULT, &d3ddm);

    не прокатывает

    да конечно если вызов метода сделать в Ассемблерной вставке

    __asm
    {
    lea eax,d3ddm
    push eax
    push 0
    mov eax,p_d3d
    push eax
    mov eax,[eax]
    call [eax+32]
    }


    всё сработает как надо

    но вот как это сделать синтаксисом - С++

    ведь ещё раз повторюсь я должен сначала отработать код на - С++

    кто в теме подскажите пожалуйста
     
    Последнее редактирование: 3 окт 2023
  2. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    462
    Заголовки с определением COM-интерфейсов на C++ как правило состоят из двух частей - дефолтные объявления в синтаксисе C++ и даунгрейд интерфейсов до C без классов.
    В данном случае:
    Код (C++):
    1.  
    2. #if !defined(__cplusplus) || defined(CINTERFACE)
    3. ...
    4. #define IDirect3D9_GetAdapterDisplayMode(p,a,b)   (p)->lpVtbl->GetAdapterDisplayMode(p,a,b)
    5. ...
    6. #else
    7. ...
    8. #define IDirect3D9_GetAdapterDisplayMode(p,a,b)   (p)->GetAdapterDisplayMode(a,b)
    9. ...
    10. #endif
    11.  
    Если приглядеться вокруг, то понятно, что Сишная версия трактует макрос DECLARE_INTERFACE таким образом, что вместо определения класса делает определение структуры с полем lpVtbl которое уже есть суть указатель на таблицу указателей на функции (структуру совпадающую получается с VTBL) которые первым дополнительным параметром принимают указатель на интерфейс. И таким образом COM можно использовать из Си без классов, а вышеобозначенные макросы позволяют писать единый код для Си и C++.

    Поэтому я бы пошёл по пути написания конвертера из синтаксиса этих довольно стандартных по структуре заголовочных файлов в синтаксис масма с похожим подходом и парой собственных макросов для естественных invoke-ов.
     
  3. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    assch,
    Код (C):
    1.  
    2. ((HRESULT (WINAPI*)(LPVOID, UINT, D3DDISPLAYMODE*))((*(LPVOID**)p_d3d)[8]))((LPVOID)p_d3d, D3DADAPTER_DEFAULT, &d3ddm);
    3.  
    Но лучше интерфейс объявить :)
     
  4. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Большое спасибо rmn, за подсказки

    синтаксически всё хорошо работает но читабельность оставляет желать лучшего
    лучше уж использовать Ассемблерные вставки там хоть для меня интуитивно всё понятно

    я понимаю что интерфейс лучше объявить
    это я так просто ради спортивного интереса
    типа можно ли вместо лексем методов прописывать их смещения в интерфейсе

    мне для примера на С++ нужен был - Microsoft DirectX SDK (June 2010)
    я его скачал но в Microsoft Visual Studio 2013
    где я ради интереса отсматриваю сишные примеры
    не как не смог сделать так чтобы виделся файл - d3dx9.h
    то есть строчка

    #include <d3dx9.h>

    не работает

    пришлось написать через кавычки полный путь

    #include "C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\d3dx9.h"

    только тогда заработало

    если в теме не подскажешь что нужно сделать
    чтобы в проекте виделся файл записанный между угловыми скобками
     
  5. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Надо просто добавить C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include в include path в настройках компилера и тогда будет работать просто #include <d3dx9.h>

    В проекте подключаемые файлы не появятся, но открыть их можно через контекстное меню (пкм по имени файла в директиве #include).
     
  6. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    196
    Не знаю как в масме, а в фасм имеется макрос "comcall", который делает удобным вызов com-методов. Просто передаём в аргументах интерфейс + метод, и на выходе получаем результат. В скрепке лежит инклуд для фасма "d3d9.inc" с описанием всех интерфейсов (структур для методов пока только три, остальные можно добавить из сишного хидера d3d9types.h). Вот пример:

    Код (ASM):
    1. format   pe console
    2. include 'win32ax.inc'
    3. include 'equates\d3d9.inc'
    4. entry    start
    5. ;//----------
    6. .data
    7. hD3d9     dd  0
    8. dspm      D3DDISPLAYMODE
    9. aid       D3DADAPTER_IDENTIFIER
    10. ;//----------
    11. .code
    12. start:   invoke   CoInitialize,0
    13.          invoke   Direct3DCreate9,D3D_SDK_VERSION
    14.          mov      [hD3d9],eax
    15.  
    16.          comcall  [hD3d9],IDirect3D9,GetAdapterDisplayMode,NULL,dspm
    17.          comcall  [hD3d9],IDirect3D9,GetAdapterIdentifier,NULL,NULL,aid
    18.  
    19.          cinvoke  printf,<10,' D3D9 example',\
    20.                           10,' ---------------------------',\
    21.                           10,' Driver......: %s',\
    22.                           10,' Name........: %s',\
    23.                           10,' Vid\Did.....: %04X:%04X',\
    24.                           10,' Resolution..: %d x %d',\
    25.                           10,' Refresh rate: %d MHz',0>,\
    26.                           aid.Driver,\
    27.                           aid.Description,[aid.VendorId],[aid.DeviceId],\
    28.                           [dspm.Width],[dspm.Height],[dspm.RefreshRate]
    29. @exit:  cinvoke  _getch
    30.         cinvoke  exit,0
    31. ;//----------
    32. section  '.idata' import data readable
    33. library   msvcrt,'msvcrt.dll', ole32,'ole32.dll', d3d9,'d3d9.dll'
    34. include  'api\msvcrt.inc'
    35. include  'api\ole32.inc'
    36. include  'api\d3d9.inc'
    d3d9.png
     

    Вложения:

    • D3D9.ZIP
      Размер файла:
      6,3 КБ
      Просмотров:
      138
    Mikl___ нравится это.
  7. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Спасибо Marylin, за участие
    --- Сообщение объединено, 7 окт 2023 ---
    Marylin, хотел собрать твой пример на своём пакете - fasm
    которым я иногда пользуюсь когда попадётся какой нибудь пример на - fasm
    но у меня там нет файлов

    include 'api\msvcrt.inc'
    include 'api\ole32.inc'
    include 'api\d3d9.inc'

    если не трудно скинь мне эти файлы пожалуйста
    я дополню ими свой пакет - fasm

    я просто хочу понять
    вот например исходя из твоего примера

    comcall [hD3d9],IDirect3D9,GetAdapterDisplayMode,NULL,dspm

    откуда компилятор знает что у метода - GetAdapterDisplayMod
    только два параметра

    ведь при обьявлении интерфейса об этом не сказано
     
  8. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    196
    Вот эти файлы (положить в папку "fasm\include\api"),
    плюс в архив положил и софт, который создаёт такие инклуды импорта.
    Просто указываешь на нужную библиотеку из папки "windows\system32\..", и получаешь на выходе готовый инклуд.
    --- Сообщение объединено, 7 окт 2023 ---
    это нужно смотреть в сишном хидере "d3d9.h" - там указаны аргументы методов.
    компилятор об этом не знает.
     

    Вложения:

    Mikl___ нравится это.
  9. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Спасибо Marylin, за файлы
    особое спасибо за - CreateFasmAPI_Include.EXE
    теперь твой код и у меня заработал на моём пакете - fasm

    я не знаю всех тонкостей программирования на - fasm
    потому что работаю на - masm32
    но был очень удивлён что если например к методу - GetAdapterDisplayMode

    приписать например лишние два параметра

    comcall [hD3d9],IDirect3D9,GetAdapterDisplayMode, NULL ,dspm, 1, 2

    то компилятор примет это за чистую монету
    и на выходе из метода стек будет на 8 байт ниже

    так же ради интереса приписал лишний параметр к функции - Direct3DCreate9

    invoke Direct3DCreate9,D3D_SDK_VERSION,0

    на выходе стек опустился ещё на 4 байта

    Marylin, это общая политика - fasm
    где прописывания параметров у функций и методов
    целиком лежит на внимательности программиста

    или всё таки у - fasm
    есть механизмы отслеживания этих ошибок
     
  10. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    196
    используй в шапке инклуд "win32axp.inc", тогда fasm будет проверять кол-во параметров.
    но для этого нужно явно прописать число этих параметров в файлах, которые лежат в папке "fasm\include\pcount".