Форум: "WinAPI";
Текущий архив: 2003.01.16;
Скачать: [xml.tar.bz2];
ВнизCoCreateInstance в TThread Найти похожие ветки
← →
dumb (2002-11-21 14:22) [0]Помогите люди добрыееееа. CoCreateInstance в TThread возвращает E_NOINTERFACE, а вне TThread работает замечательно.
Вот конструкция:
CoInitialize(nil);
CoInitializeSecurity(nil, 0, nil, nil, 0, 3, nil, 0, nil);
hr := CoCreateInstance(CLSID_APPKRNL, nil, CLSCTX_SERVER, IID_IAPP, pIApp);
← →
Marcus (2002-11-21 18:04) [1]Ну для начала, думаю надо CoInitializeEx(nil, COINIT_MULTITHREADED or COINIT_APARTMENTTHREADED)
← →
Набережных С. (2002-11-21 18:25) [2]>Marcus (21.11.02 18:04)
У тебя жар?
>dumb (21.11.02 14:22)
Мало информации. Обычно E_NOINTERFACE возвращается, когда требуется межапартаментный маршаллинг, а менеджер не знает, как его осуществить, т.е. в реестре для запрошенного интерфейса нет подключа ProxyStubClsid32. Разумеется, кроме случая, когда интерфейс объектом действительно не поддерживается.
← →
dumb (2002-11-21 18:34) [3]>Marcus (21.11.02 18:04)
Не помогло.
>Набережных С. (21.11.02 18:25)
Ну и что же мне делать? Забыть о создании этого объекта в TThread?
← →
Marcus (2002-11-21 18:41) [4]В принципе можешь попробовать создавать объект в основном потоке и маршалить его в другой. См. ф-ии CoMarshalInterThreadInterfaceInStream и CoGetInterfaceAndReleaseStream.
← →
dumb (2002-11-21 19:38) [5]Когда я делаю
CoInitialize(nil);
CoCreateInstance(CLSID_AVGKRNL, nil, CLSCTX_SERVER, IID_IAVG, pIAvg);
hr := CoMarshalInterThreadInterfaceInStream(IDispatch, pIAvg as IUnknown, IStream (pStream));
// создаем поток
до создания потока, CoMarshalInterThreadInterfaceInStream возвращает E_NOINTERFACE. Что за издевательство?
← →
Marcus (2002-11-21 19:46) [6]Может дело в том, что 1-ый параметр у тебя IID_IDispatch, а второй pIAvg as IUnknown. Попробуй
CoMarshalInterThreadInterfaceInStream(IID_IAVG, pIAvg, IStream (pStream));
← →
Набережных С. (2002-11-21 19:47) [7]
>Marcus (21.11.02 18:41)
Будет то-же самое. В чем разница-то? Если, конечно, причина не в чем-то другом.
>dumb (21.11.02 18:34)
Сделай интерфейс совместимым с автоматизацией (галочку в библиотеке типов поставь). Соответственно, в методах интерфейса должны использоваться типы, совместимые с автоматизацией. И, кстати, ты в курсе, что CoInitializeSecurity вызывается один раз для всего приложения, а не для каждого потока, и, если где-то уже было обращение к функциям активации объектов, то она уже вызывалась неявно?
← →
Набережных С. (2002-11-21 19:56) [8]>dumb (21.11.02 19:38)
Покажи объявление класса, секцию инициализации его модуля и сообщи, где находится класс.
← →
dumb (2002-11-21 20:08) [9]> Набережных С. (21.11.02 19:56)
Вот как описан класс. Какая дополнительная информация нужна?
unit AVG_TLB;
interface
uses ActiveX, ComObj, Windows;
const CLSID_AVGKRNL: TGuid = "{67B30939-3B35-11d2-A595-002018648BA7}";
IID_IAVG: TGuid = "{67B30940-3B35-11d2-A595-002018648BA7}";
IID_IAVGTEST: TGuid = "{67B30941-3B35-11d2-A595-002018648BA7}";
FACILITY_AVG = 64;
FACILITY_AVGKRNL = 65;
type
TAVGVERSION = packed record
avg_version: DWORD;
avi_version: DWORD;
avi_mikro: Byte; // "A" az "Z"
build: DWORD;
revision: DWORD;
build_time: DWORD;
avi_date: DWORD;
trial_date: DWORD; //0=EXPIRED, >0 valid, n-1 days left
current_date: DWORD;
majorVersion: BYTE;
minorVersion: WORD;
minorWaiting: WORD;
lng: BYTE;
is_trial: BYTE; // 0=not, otherwise it is a trial}
end;
IAvg = interface(IUnknown)
["{67B30940-3B35-11d2-A595-002018648BA7}"]
function GetVersion(var AVGVersion: TAVGVERSION): HResult stdcall;
function CheckError(ar: HResult; var Error: PChar): string stdcall;
end;
IAvgTest = interface(IUnknown)
["{67B30941-3B35-11d2-A595-002018648BA7}"]
function ScanFile(szFile: PChar; origName: PChar): HResult stdcall;
procedure GetMoreInfo(var pMoreInfo: PChar) safecall;
end;
implementation
end.
← →
dumb (2002-11-21 20:15) [10](это из API антивируса Grisoft AVG)
Может еще кто знает клевый антивирус к которому можно подцепляться через COM? (Kaspersky не предлагать, т.к. $500 в год мне не потянуть, хотя антивирус хороший и имеет клевый API).
Кстати, AVG сканнер можно запустить из потока как отдельное приложение, дождаться завершения и т.д. Но большой минус - скорость выполнения. Для сравнения: через COM - около 100мс, как отдельное приложение - около 500мс.
← →
Набережных С. (2002-11-21 20:40) [11]Найди этот класс в реестре и посмотри, какую он поддерживает потоковую модель. Если free или both, то замени CoInitialize(nil) на CoInitializeEx(nil, COINIT_MULTITHREADED).
Найди в реестре по GUID интерфейсы и посмотри, есть ли у них подключ ProxyStubClsid32.
Как я понимаю, объект находится в DLL. Можно рискнуть и попытаться обойтись без маршаллинга, просто передав интерфейс в поток из основного. Есть вероятность, что все отработает нормально, но гарантий здесь никаких. Причем проблемы могут вылезти не сразу.
← →
dumb (2002-11-22 22:37) [12]Вроде работает, если создать и передавать потокам. На всякий пожарный вызов загнал в Synchronize. Посмотрим...
← →
dumb (2002-11-29 18:27) [13]Ура!! Граждане, господа, това-ри-щи. Заработало!! После переписки с поизводителем выяснилось, что они забыли добавить ThreadingModel = Apartment для InprocServer32. Ну кто бы мог подумать-то, а? что они свои COMы руками регистрируют!?
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2003.01.16;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.008 c