FTM или Специальный маршалинг
От: Kolex Россия  
Дата: 22.06.03 09:21
Оценка:
Hi, all!

Есть приложение, которое работает в основном потоке проинициализированном через OleInitialize(NULL). (Если процесс проинициализировать через CoInitializeEx(NULL, COINIT_MULTITHREADED), то проблем не будет вообще никаких, но мне так нельзя).
В этом же процессе создается поток, проинициализированный через CoInitializeEx(NULL, COINIT_MULTITHREADED). В потоке выполняется код из dll-библиотеки.

Далее во втором потоке мне необходимо создать COM-объект (потоковая модель Both) через CoCreateInstance, реализованный в основном приложении и использующий FTM (без прокси), так как дальнейшие вызовы методов этого объекта должны выполняться во втором потоке:

class ATL_NO_VTABLE IFormSupportImpl :
public IDispatchImpl<IFormSupport, &IID_IFormSupport, &LIBID_ModSystemForms>,
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<IFormSupportImpl, &CLSID_FormSupport>
{
public:
DECLARE_REGISTRY_RESOURCEID(IDR_FORMSUPPORT)

public:
IFormSupportImpl(){};
~IFormSupportImpl(){};

public:
BEGIN_COM_MAP(IFormSupportImpl)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IFormSupport)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
END_COM_MAP()

DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_GET_CONTROLLING_UNKNOWN()

HRESULT FinalConstruct()
{
HRESULT hr = CoCreateFreeThreadedMarshaler(
GetControllingUnknown(), &m_pUnkMarshaler.p);
return hr;
}

void FinalRelease()
{
m_pUnkMarshaler.Release();
}

CComPtr<IUnknown> m_pUnkMarshaler;

public:
// IFormSupport implementation
};

На Win2000 все работает как часы. Но на NT4 6SP все равно создается прокси и вызовы методов COM-объекта выполняются в основном потоке. В чем может быть проблема?

----------------------------------------------------
Для обхода проблемы я попытался реализовать свой маршаллер.

STDMETHODIMP IMarshalImpl::GetUnmarshalClass(...)
{
*pCid = CLSID_FormSupportProxy;
return S_OK;
}

STDMETHODIMP IMarshalImpl::GetMarshalSizeMax(...)
{
*pSize = 0;
return S_OK;
}

STDMETHODIMP IMarshalImpl::MarshalInterface(...)
{
return S_OK;
}

FormSupportProxy реализован также в основном приложении.

После вызова MarshalInterface выполнение возвращается во второй поток в точку вызова CoCreateInstance c ошибкой "Класс не зарегистрирован". FormSupportProxy при этом не создается, в реестре зарегистрирован (потоковая модель Both; регистрировал его как LocalServer32, так и InprocServer32).

Причем, если реализацию прокси вынести в отдельную библиотеку, то прокси успешно создается!

Что же здесь не так?

Заранее спасибо за ответы.
Re: FTM или Специальный маршалинг
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 23.06.03 03:42
Оценка:
Здравствуйте, Kolex, Вы писали:

[]

K>На Win2000 все работает как часы. Но на NT4 6SP все равно создается прокси и вызовы методов COM-объекта выполняются в основном потоке. В чем может быть проблема?


Далее во втором потоке мне необходимо создать COM-объект (потоковая модель Both) через CoCreateInstance, реализованный в основном приложении и использующий FTM (без прокси),


Вот здесь не понял.
Конкретно, где создается "Both with FTM" объект?

K>----------------------------------------------------

K>Для обхода проблемы я попытался реализовать свой маршаллер.

Ндя...
Здесь
Автор(ы): Чистяков В.Ю.
кое-что можно почитать.

хъ

K>После вызова MarshalInterface выполнение возвращается во второй поток в точку вызова CoCreateInstance c ошибкой "Класс не зарегистрирован". FormSupportProxy при этом не создается, в реестре зарегистрирован (потоковая модель Both; регистрировал его как LocalServer32, так и InprocServer32).


Дык сервер-то exe что-ли?

K>Причем, если реализацию прокси вынести в отдельную библиотеку, то прокси успешно создается!


Тогда зачем тебе FTM?

K>Что же здесь не так?


[]

Ты привел много информации не по существу.
Re[2]: FTM или Специальный маршалинг
От: Kolex Россия  
Дата: 23.06.03 04:25
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

K>>На Win2000 все работает как часы. Но на NT4 6SP все равно создается прокси и вызовы методов COM-объекта выполняются в основном потоке. В чем может быть проблема?


AS>Вот здесь не понял.

AS>Конкретно, где создается "Both with FTM" объект?

Нужно создать "Both with FTM" объект во втором потоке. А сама реализация объекта должна находиться в основном exe-шнике.

K>>Причем, если реализацию прокси вынести в отдельную библиотеку, то прокси успешно создается!


AS>Тогда зачем тебе FTM?


AS>Ты привел много информации не по существу.


Просто не хотел ничего упустить.

В кратце задача такая:

Есть exe-приложение, в котором реализован некий COM-объект (FormSupport) (приложение должно быть проинициализировано через OleInitialize (STM)). Есть dll, код которой выполняется в отдельном потоке. Необходимо из второго потока через CoCreateInstance создать COM-объект (FormSupport). Методы этого объекта должны выполняться без прокси во втором потоке.

Причем все это должно работать на NT4 (на Win2000 спасает, если сделать COM-объект "Both with FTM")
Re[3]: FTM или Специальный маршалинг
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 23.06.03 05:14
Оценка:
Здравствуйте, Kolex, Вы писали:

[]

Я еще больше запутался. Как для объекта FormSupport, реализованного в EXE-модуле ты умудрился задать потоковую модель Both?

Для коклассов в exe потоковая модель задается путем вызова CoInit... (OleInit...), но никак не в реестре.

Давай нормально объясни какие коклассы в каких модулях реализованы и в каких потоках создаются.
Re[4]: FTM или Специальный маршалинг
От: Kolex Россия  
Дата: 23.06.03 05:30
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Для коклассов в exe потоковая модель задается путем вызова CoInit... (OleInit...), но никак не в реестре.


Действительно, согласен, both здесь не причем. Меня интересует поведение free-threaded маршаллера.
Re[5]: FTM или Специальный маршалинг
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 23.06.03 05:47
Оценка:
Здравствуйте, Kolex, Вы писали:

[]

K>Действительно, согласен, both здесь не причем. Меня интересует поведение free-threaded маршаллера.


А чего в нем непонятного. С помощью него клиенту передается прямой указатель на интерфейс. Все подробно разжевано в MSDN и на RSDN упоминалось не раз. Можешь поискать.

А с чего ты рещил, что под NT тебе возвращается прокся?
Re[6]: FTM или Специальный маршалинг
От: Kolex Россия  
Дата: 23.06.03 06:45
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>А чего в нем непонятного. С помощью него клиенту передается прямой указатель на интерфейс. Все подробно разжевано в MSDN и на RSDN упоминалось не раз. Можешь поискать.


Как должно быть в теории я себе очень хорошо представляю. На Win2000 именно так все и работает.

AS>А с чего ты рещил, что под NT тебе возвращается прокся?


Запускал на NT и смотрел в отладчике. При вызове методов объекта из второго потока стек вызовов уходит в rpcrt4.dll, а метод выполняется уже в основном потоке.

Я этой проблемой занимаюсь уже порядочно времени. Перечитал кучу статей, но причин так и не нашел.

Будет время, могу собрать небольшой тестовый проектик на VC7.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.