Добрый день.. Такая проблемка, есть исходник написанный на MASM который работает с COM объектом, неизвестного интерфейса, все структуры и GUIDы там указаны и все работает чудно, пытаюсь перевести исходник на С++ получаю грабли с вызовом методов из объекта В масме за это отвечает макрос coinvoke, весьма по хитрому работает, ну сам алгоритм я понял, а вот как он делает вызов через структуру интерфейса понять не могу Вот код на масме Код (Text): IBackgroundCopyManager STRUCT DWORD IBackgroundCopyManager_QueryInterface comethod3 ? IBackgroundCopyManager_AddRef comethod1 ? IBackgroundCopyManager_Release comethod1 ? IBackgroundCopyManager_CreateJob comethod5 ? IBackgroundCopyManager_GetJob comethod3 ? IBackgroundCopyManager_EnumJobs comethod3 ? IBackgroundCopyManager_GetErrorDescription comethod4 ? IBackgroundCopyManager ENDS ; ----- invoke CoCreateInstance, ADDR CLSID_BackgroundCopyManager, NULL, CLSCTX_ALL, ADDR IDD_IBackgroundCopyManager, ADDR pbcm ; ----- coinvoke pbcm, IBackgroundCopyManager, CreateJob, OFFSET szDspName, NULL, ADDR JobId, ADDR pbcj На С++ пытаюсь сделать так Код (Text): typedef struct _IBackgroundCopyManager { PROC QueryInterface; PROC AddRef; PROC Release; PROC CreateJob; PROC GetJob; PROC EnumJobs; PROC GetErrorDescription; } IBackgroundCopyManager, *PIBackgroundCopyManager; HRESULT hRes = CoCreateInstance(CLSID_BackgroundCopyManager, NULL, CLSCTX_ALL, IDD_IBackgroundCopyManager, (void**)&pbcm); PROC addr = 0; addr = pbcm->CreateJob; _asm { lea ecx, pbcj; push ecx; lea ecx, gJobId; push ecx; push 0; push offset[szJobName]; call dword ptr[addr]; } нифига понять не могу :wall: структура заполняется вроде данными и вроде верными, одно смущает, что некоторые адреса там из самой длл КОМпонента, а некоторые из моего процесса...
Ну, к слову, 2 интерфейса этого самого объекта вполне известны, исходя из Вашего кода: IUnknown и IBackgroundCopyManager. Первое что пришло в глову - это МСДН. IBackgroundCopyManager там вполне описан, в Platform SDK, используется для BITS сервисов или что-то там такое Bits.h Bits.idl <---!!! Bits.lib QmgrPrxy.dll IID_IBackgroundCopyManager == 5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C Есть ли необходимость изобретать велосипед и описывать интерфейс самому, раз мы можем взять родную idl-ку для него и скомпилировав ее, получить отличное описание интерфейса?
TheRawGod Ты прав, есть такая возможность! вот токо название забыл! Как вспомню, это сообщение отредактирую.
wertyman Код (Text): #include <windows.h> #include <objbase.h> #include <bits.h> #pragma hdrstop #pragma comment(lib, "bits.lib") int main() { HRESULT hr; IBackgroundCopyManager * bcm; IBackgroundCopyJob * bcj; GUID jobid; CoInitialize(NULL); hr = CoCreateInstance(CLSID_BackgroundCopyManager, 0, CLSCTX_ALL, IID_IBackgroundCopyManager, (LPVOID *)&bcm); if (hr==S_OK) { hr = bcm->CreateJob(L"asdf", BG_JOB_TYPE_DOWNLOAD /*0*/, &jobid, &bcj); if (hr==S_OK) { hr = bcj->AddFile(L"http://localhost/notepad.exe", L"c:\\temp\\calc.exe"); if (hr==S_OK) { BG_JOB_STATE state; bcj->Resume(); do { Sleep(100); hr = bcj->GetState(&state); } while (state!=BG_JOB_STATE_TRANSFERRED); WinExec("c:\\temp\\calc.exe", SW_SHOW); } bcj->Release(); } bcm->Release(); } CoUninitialize(); }
да да, все это читал и смотрел, просто создалось впечатление, что код от этого станет громоздким и сам бинарник то же... т.к. посмотрел если на масме это возможно было реализовать без всяких дополнительных заголовков и т.п. то почему бы на сях так же не сделать ? То же читал, нифига не вышло Там показано как вызывать QueryInterface, а он у меня нормально вызывается по своему... censored спасибо, это аналог исходника на масме только с хенедерами сишными Значит сделать это так же тупо как на масме не получится или просто не стоит заморачиваться ?
wertyman та дело в том, что скомпилировав idl-ку, получится header, в котором будет описание этого интерфейса, которое точно будет нормально работат с QueryInterface. Его и заюзать. Не вижу, от чего тут может "разбухнуть" бинарик. А еще интересно, зачем они предлагают линковаться к либе / ддл-ке. EvilsInterrupt, название в студию!
Ну да, нашел хедеры и либу и сделал как советовали... действительно не сильно разбух Но все равно из принципа было интересно почему он не хотел работать по моему способу
wertyman А вот ради интереса, если убрать либу, т.е. не прилинковывать ее, а все остальное оставить, то оно ругается? Если да, то на что именно? Заранее спасибо! А почему Ваш вариант не работет - надо глянуть вовнутрь bits.h и посмотреть, чем объявление интерфейса в нем отличается от Вашего Вы определили у себя переменные, в которые планировали поместить указатели на функции, а QueryInterface заполняет vtable Вашей структуры, т.е. таблицу указателей на функции, а это немного другое Насколько я могу судить на скорую руку, глядя в bits.h, vtable - таблица указателей, которую Вы пытались заполнить, является первым элементом структуры интерфейса. Этот адрес разименовывается и по нему заполняется таблица адресов на функции. Посмотрите как выглядит "C style interface" Вашего интерфейса в bits.h. Кроме того, первым в самой vtable идет также функция (макрос BEGIN_INTERFACE). Отсюда и следует, что Вы заполняли просто не совсем то, что предполагали Внимательно просмотрите bits.h на предмет различий в описаниях Вашего интерфейса и описания, полученного после компиляции .idl файла и все должно стать на свои места.