![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Не работает Cocreateinstance
Int23 © (2009-05-21 09:34:00)Использую компоненты DSPack(работа с вебкамерами). Когда запускаю пример в котором компоненты находятся на форме, то всё работает. ТОлько создаю программно эти компоненты внутри своего компанента, то result := Cocreateinstance(CLSID_SampleGrabber, nil, CLSCTX_INPROC ,IID_IBASEFilter, AFilter) = S_OK; возвращает
False
Григорьев Антон (2009-05-21 17:19:00) [1]
> Palladin © (21.05.09 11:20) [13]
> Удивись :)
Это давно известный эффект - что во многих случаях, если mutithreaded apartment уже создан, то нить может быть помещена туда и без явного вызова CoInitializeEx. Но гарантии, что она будет помещена туда всегда, нет, поэтому вызывать CoInitializeEx всё равно нужно В КАЖДОЙ нити, использующей COM, а то однажды программа всё-таки может не заработать.
Проблема усугубляется тем, что в предварительной (версия 0.9) документации на DCOM было утверждение, что CoInitializeEx с параметром COINIT_MULTITHREADED надо вызывать только один раз, а остальные нити будут в этот апартамент помещаться по умолчанию. И хотя в версии 1.0 это уже было исправлено, ошибочное утверждение успело разойтись по сети.
Источник информации - книга Э. Трельсена про ATL и COM.
Сергей М. (2009-05-21 11:29:00) [2]
> Palladin © (21.05.09 11:20) [13]
Удивился)
Отзываю свое утверждение из [12] на переработку в Recycled bin)
Int23 (2009-05-21 11:25:00) [3]Вообщем вызвал в дочернем потоке и всё заработало. Спасибо всем
Palladin (2009-05-21 11:20:00) [4]
> Сергей М. © (21.05.09 11:11) [12]
Удивись :)
Uses
ActiveX,
Comobj;
Type
TMThread=Class(TThread)
Protected
Procedure Execute; Override;
End;
Procedure TMThread.Execute;
Var
v:OleVariant;
Begin
Try
v:=CreateOleObject('Word.Application');
Except
On E:Exception Do MessageBox(0,PChar(E.Message),'Exception',MB_OK);
End;
v.Quit;
End;
procedure TForm1.Button1Click(Sender: TObject);
begin
With TMThread.Create(True) Do
Begin
FreeOnTerminate:=True;
Resume;
End;
end;
initialization
CoInitializeEx(nil, COINIT_MULTITHREADED);
end.
Сергей М. (2009-05-21 11:11:00) [5]
> я в основном модуле с компонентом прописал CoInitializeEx(nil,
> COINIT_MULTITHREADED);
Модуль, основной он или не основной, тут вообще ни причем.
Значение имеет в каком потоке эта ф-ция вызывается.
А вызываться она должна в том же самом потоке, в котором будет осуществляться работа с COM-подсистемой.
Palladin (2009-05-21 10:54:00) [6]
> Int23 (21.05.09 10:46) [9]
Это CO_E_NOTINITIALIZED = $800401F0
Значит все таки не вызвал.
Palladin (2009-05-21 10:48:00) [7]
> Anatoly Podgoretsky © (21.05.09 10:36) [8]
Посмотри справку,
The CoInitialize function initializes the Component Object Model(COM) library. You must initialize the library before you can call its functions. Applications must call CoInitialize before they make any other COM library calls with two exceptions: the CoGetMalloc function, and memory allocation calls.
Int23 (2009-05-21 10:46:00) [8]У меня Cocreateinstance возвращает число -2147221008. ПРичём я в основном модуле с компонентом прописал CoInitializeEx(nil, COINIT_MULTITHREADED);
Anatoly Podgoretsky (2009-05-21 10:36:00) [9]> Palladin (21.05.2009 10:19:05) [5]
Посмотри справку, среди возвращаемых значений, нет ничего про CoInitialize
Palladin (2009-05-21 10:35:00) [10]
> Int23 (21.05.09 10:32) [6]
надеюсь CoInitialize производится как CoInitializeEx(nil, COINIT_MULTITHREADED); ?
90% Антона скорее всего попадут именно в этот нюанс :)
Int23 (2009-05-21 10:32:00) [11]Palladin
Точно. Я создаю отдельный поток и в нём создаю эти компоненты. А вообще можно в отдельном потоке работать с ДиректСшоу?
Palladin (2009-05-21 10:19:00) [12]
> Единственно он ошибся с CoInitialize это не требуется на
> данном шаге.
Не ошибся, а предположил, что создание объекта происходит не в основном потоке.
Anatoly Podgoretsky (2009-05-21 10:18:00) [13]А нафига ты вызывал GetLastError, вместо чтения справки? Он же не используется, о чем Григорьев Антон уже сказал. Единственно он ошибся с CoInitialize это не требуется на данном шаге.
Int23 (2009-05-21 10:05:00) [14]У меня CoInitialize вызывается в инициализатион. Вот что возвращает SysErrorMessage(GetLastError)
"Операция успешно завершена"
Григорьев Антон (2009-05-21 09:42:00) [15]
> Palladin © (21.05.09 09:36) [1]
GetLastError тут не нужен, возвращаемое значение типа HRESULT уже содержит достаточно информации.
P.S. Процентов 90, что CoInitialize не вызван.
Palladin (2009-05-21 09:36:00) [16]Ну а проанализировать, что же возвращается и GetLastError, религия не позволяет?