COM в Си

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by greki_hoy, 2 Nov 2010.

  1. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    эээ... писал ответить сюда на форум а пока написал тему быстренько снесли удалять написанное жалко может кому то пригодится
    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    дык все просто ручками создаеш таблицу
    Code:
    typedef struct _VTABLE
    {
    void (*somefunc)(...);
    }VTABLE;
    typedef struct _IInterface
    {
     VTABLE *__pfvtbl;
    }IInterface; 
    
    потом получаеш указатель на интерфейс и
    инициализируеш свой указатель
    Code:
    IInterface myp;
    CoCreateInstance(...);
    myp->__pfvtbl->somefunc(myp, arg1, arg2, ...);
    
    можно же готовые интерфейсы взять описанные за нас
    а можно и ручкми создать
    просто узнаеш смещения нужных методов в таблице настоящей а можно и
    без заполнителей польностью описать интерфейс
    Code:
    typedef struct _vtblREGEX{
    char pad1[...];
    void (*compile)(...);
    char pad2[...];
    void (*pattern)(...);
    } vtblREGEX;
    typedef struct _IREGEX{
    vtblREGEX *__pfvtbl;
    } IREGEX;
    
    так описываеш только нужные тебе функции и все
    можно пользоватся так
    Code:
    IREGEX myp;
    CoCreateInstance(&myp);
    myp->__pfvtbl->compile(myp, arg1, arg2, ...);
    myp->__pfvtbl->pattern(myp, arg1, arg2, ...);
    
     
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Тему удалил потому что нашел как это пашет, но что-то не катит всё равно. Вообще вот что надо было:


    Потребовалось один код переписать с С++ на С. Код под Win7.
    на С++ выглядел код так (и работало нормально):
    Code:
    IFileOperation *pFileOp = NULL;
    BIND_OPTS3 bo = {0};
    wchar_t EIFOMoniker[] = L"Elevation:Administrator!new:{3ad05575-8857-4850-9277-11b85bdb8e09}";
    ...
    bo.cbStruct = sizeof(bo);
    bo.dwClassContext = CLSCTX_LOCAL_SERVER;
    
    if (CoGetObject(EIFOMoniker, &bo, __uuidof(IFileOperation), reinterpret_cast< void ** >(&pFileOp)) == S_OK) 
    ..
    
    Пытался переписать на Си, вышло вот что:

    Code:
    IFileOperationVtbl* pFileOp = NULL;
    BIND_OPTS3 bo = {0};
    wchar_t EIFOMoniker[] = L"Elevation:Administrator!new:{3ad05575-8857-4850-9277-11b85bdb8e09}";
    ...
    bo.cbStruct = sizeof(bo);
    bo.dwClassContext = CLSCTX_LOCAL_SERVER;
    
    if (CoGetObject(EIFOMoniker, (BIND_OPTS*)&bo, &IID_IFileOperation, (void **)&pFileOp) == S_OK)
    
    Но данный код почему-то не работает. CoGetObject возвращая статус E_INVALIDARG (0x80070057L)
     
  3. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Всё сам разобрался) оказывается тупость была чуть в другом
     
  4. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    2slesh
    попробуй так
    Code:
    BIND_OPTS3 bo;
    wchar_t EIFOMoniker[] = L"Elevation:Administrator!new:{3ad05575-8857-4850-9277-11b85bdb8e09}";
    bo.cbStruct = sizeof(BIND_OPTS); // <---- BIND_OPTS not BIND_OPTS3
    bo.dwClassContext = CLSCTX_LOCAL_SERVER;
    
     
    1 person likes this.
  5. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Это я заметил и исправил, там бам был глюк в другом чуть.
    В частности когда юзал как шеллкод, то забывал гуид копировать.