Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

CoCreateInstance в TThread [D5, WinXP]


dumb ©   (2002-11-21 14:22:00) 

Помогите люди добрыееееа. 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);


dumb   (2002-11-29 18:27:00) [1]

Ура!! Граждане, господа, това-ри-щи. Заработало!! После переписки с поизводителем выяснилось, что они забыли добавить ThreadingModel = Apartment для InprocServer32. Ну кто бы мог подумать-то, а? что они свои COMы руками регистрируют!?


dumb   (2002-11-22 22:37:00) [2]

Вроде работает, если создать и передавать потокам. На всякий пожарный вызов загнал в Synchronize. Посмотрим...


Набережных С.   (2002-11-21 20:40:00) [3]

Найди этот класс в реестре и посмотри, какую он поддерживает потоковую модель. Если free или both, то замени CoInitialize(nil) на CoInitializeEx(nil, COINIT_MULTITHREADED).

Найди в реестре по GUID интерфейсы и посмотри, есть ли у них подключ ProxyStubClsid32.

Как я понимаю, объект находится в DLL. Можно рискнуть и попытаться обойтись без маршаллинга, просто передав интерфейс в поток из основного. Есть вероятность, что все отработает нормально, но гарантий здесь никаких. Причем проблемы могут вылезти не сразу.


dumb   (2002-11-21 20:15:00) [4]

(это из API антивируса Grisoft AVG)

Может еще кто знает клевый антивирус к которому можно подцепляться через COM? (Kaspersky не предлагать, т.к. $500 в год мне не потянуть, хотя антивирус хороший и имеет клевый API).

Кстати, AVG сканнер можно запустить из потока как отдельное приложение, дождаться завершения и т.д. Но большой минус - скорость выполнения. Для сравнения: через COM - около 100мс, как отдельное приложение - около 500мс.


dumb   (2002-11-21 20:08:00) [5]

> Набережных С. (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.


Набережных С.   (2002-11-21 19:56:00) [6]

>dumb (21.11.02 19:38)
Покажи объявление класса, секцию инициализации его модуля и сообщи, где находится класс.


Набережных С.   (2002-11-21 19:47:00) [7]


>Marcus (21.11.02 18:41)
Будет то-же самое. В чем разница-то? Если, конечно, причина не в чем-то другом.

>dumb (21.11.02 18:34)
Сделай интерфейс совместимым с автоматизацией (галочку в библиотеке типов поставь). Соответственно, в методах интерфейса должны использоваться типы, совместимые с автоматизацией. И, кстати, ты в курсе, что CoInitializeSecurity вызывается один раз для всего приложения, а не для каждого потока, и, если где-то уже было обращение к функциям активации объектов, то она уже вызывалась неявно?


Marcus   (2002-11-21 19:46:00) [8]

Может дело в том, что 1-ый параметр у тебя IID_IDispatch, а второй pIAvg as IUnknown. Попробуй
CoMarshalInterThreadInterfaceInStream(IID_IAVG, pIAvg, IStream (pStream));


dumb   (2002-11-21 19:38:00) [9]

Когда я делаю


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 18:41:00) [10]

В принципе можешь попробовать создавать объект в основном потоке и маршалить его в другой. См. ф-ии CoMarshalInterThreadInterfaceInStream и CoGetInterfaceAndReleaseStream.


dumb   (2002-11-21 18:34:00) [11]

>Marcus (21.11.02 18:04)
Не помогло.

>Набережных С. (21.11.02 18:25)
Ну и что же мне делать? Забыть о создании этого объекта в TThread?


Набережных С.   (2002-11-21 18:25:00) [12]

>Marcus (21.11.02 18:04)
У тебя жар?

>dumb (21.11.02 14:22)
Мало информации. Обычно E_NOINTERFACE возвращается, когда требуется межапартаментный маршаллинг, а менеджер не знает, как его осуществить, т.е. в реестре для запрошенного интерфейса нет подключа ProxyStubClsid32. Разумеется, кроме случая, когда интерфейс объектом действительно не поддерживается.


Marcus   (2002-11-21 18:04:00) [13]

Ну для начала, думаю надо CoInitializeEx(nil, COINIT_MULTITHREADED or COINIT_APARTMENTTHREADED)


Наверх

Титульная страница Поиск, карта сайта Написать письмо