Инициализации с помощью atl интерфейса в dll
От: naston  
Дата: 30.03.07 06:10
Оценка:
Здравствуйте! Я новичок в atl. Может кто подскажет что за проблема. Есть проект dll. Есть Atl с помощью которого реализован некий интерфейс. В dll в классе конструкторе который запускает рабочую нить dll нужно проинициализировать некий массив с помощью интерфейса atl.
//создаем объект IRubegList

CComPtr<IRubegList> spIRubegList;
HRESULT hr = spIRubegList.CoCreateInstance (CLSID_RubegList); создает нормально
//ShowError(hr);

//Задаем код поддержки интерфейса
hr = spIRubegList->SetInterfaceSupportVersionCode (117506320); виснет после:




_NoAddRefReleaseOnCComPtr<T>* operator->() const throw()
{
ATLASSERT(p!=NULL);
return (_NoAddRefReleaseOnCComPtr<T>*)p;

}

Подскажите пожалуйста, что может быть за проблема.
интерфейс импортирую так:
#import "C:\Рубеж\R08Srv.exe" no_implementation no_namespace raw_interfaces_only raw_native_types named_guids
Re: Инициализации с помощью atl интерфейса в dll
От: Аноним  
Дата: 30.03.07 14:07
Оценка:
Здравствуйте, naston, Вы писали:

N>Здравствуйте! Я новичок в atl. Может кто подскажет что за проблема. Есть проект dll. Есть Atl с помощью которого реализован некий интерфейс. В dll в классе конструкторе который запускает рабочую нить dll нужно проинициализировать некий массив с помощью интерфейса atl.

Информации недостаточно, самое интересное это скорее всего взаимодействие потоков с вашим объектом, а то как вы импортируете — роли не играет. Гадаем:
1) Интерфейс создаётся и используется в одном и том же потоке? Если нет — нужно маршаллить.
2) Используется ли интерфейс в рабочем потоке? Если да — зовёт ли поток CoInitialize? А в основном потоке СОМ точно инициализирован, кстати говоря?
Re[2]: Инициализации с помощью atl интерфейса в dll
От: naston  
Дата: 30.03.07 16:01
Оценка:
Здравствуйте, большое спасибо за ответ.
//1) Интерфейс создаётся и используется в одном и том же потоке?

Интерфейс и создается и используется в одном потоке.
Сегодня выяснила, что когда интерфейс создавать в основном потоке, то похоже происходит взаимоблокировка потоков и приложение виснет, если же создвавать интефейс в отдельном параллельном потоке, то все нормально, единственно, не знаю, как можно их нормально синхронизировать так, чтобы дополнительный поток сначала проинициализировал переменные, а потом уже выполнялся основной(DllMain), Event и критические секции не помогли . Пришлось поступить не очень красиво, создать некую переменную-флаг и возвести ее когда в дополнительном потоке массив будет заполнен, тогда в основном потоке можно работать с этим массивом.
Может Вы посоветуете что-нибудь другое?
Re[3]: Инициализации с помощью atl интерфейса в dll
От: Аноним  
Дата: 31.03.07 11:32
Оценка:
Здравствуйте, naston, Вы писали:

N>Сегодня выяснила, что когда интерфейс создавать в основном потоке, то похоже происходит взаимоблокировка потоков и приложение виснет, если же создвавать интефейс в отдельном параллельном потоке, то все нормально, единственно, не знаю, как можно их нормально синхронизировать так, чтобы дополнительный поток сначала проинициализировал переменные, а потом уже выполнялся основной(DllMain), Event и критические секции не помогли . Пришлось поступить не очень красиво, создать некую переменную-флаг и возвести ее когда в дополнительном потоке массив будет заполнен, тогда в основном потоке можно работать с этим массивом.

N>Может Вы посоветуете что-нибудь другое?

А вы эти упражнения не в DLLMain выполняете случаем? Если да — то так нельзя: создание СОМ объекта влечёт вызов LoadLibrary + нельзя заниматься синхронизацией потоков.

http://download.microsoft.com/download/a/f/7/af7777e5-7dcd-4800-8a0a-b18336565f5b/DLL_bestprac.doc

You should never perform the following tasks from within DllMain:
Call LoadLibrary or LoadLibraryEx (either directly or indirectly). This can cause a deadlock or a crash.
Synchronize with other threads. This can cause a deadlock.
Acquire a synchronization object that is owned by code that is waiting to acquire the loader lock. This can cause a deadlock.
Initialize COM threads by using CoInitializeEx. Under certain conditions, this function can call LoadLibraryEx.
Call the registry functions. These functions are implemented in Advapi32.dll. If Advapi32.dll is not initialized before your DLL, the DLL can access uninitialized memory and cause the process to crash.
Call CreateProces. Creating a process can load another DLL.
Call ExitThread. Exiting a thread during DLL detach can cause the loader lock to be acquired again, causing a deadlock or a crash.
Call CreateThread. Creating a thread can work if you do not synchronize with other threads, but it is risky.
Create a named pipe or other named object (Windows 2000 only). In Windows 2000, named objects are provided by the Terminal Services DLL. If this DLL is not initialized, calls to the DLL can cause the process to crash.
Use the memory management function from the dynamic C Run-Time (CRT). If the CRT DLL is not initialized, calls to these functions can cause the process to crash.
Call functions in User32.dll or Gdi32.dll. Some functions load another DLL, which may not be initialized.
Use managed code.

The following tasks are safe to perform within DllMain:
Initialize static data structures and members at compile time.
Create and initialize synchronization objects.
Allocate memory and initialize dynamic data structures (avoiding the functions listed above.)
Set up thread local storage (TLS).
Open, read from, and write to files.
Call functions in Kernel32.dll (except the functions that are listed above).
Set global pointers to NULL, putting off the initialization of dynamic members. In Microsoft Windows Vista™, you can use the one-time initialization functions to ensure that a block of code is executed only once in a multithreaded environment.
Re[4]: Инициализации с помощью atl интерфейса в dll
От: naston  
Дата: 31.03.07 19:13
Оценка:
Доброго времени суток, спасибо за полезную инфу, я тоже уже поняла, что так делать нельзя. Зато теперь буду знать .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.