Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.10.2012, 14:56   #1
DRFRIMEN
Пользователь
 
Регистрация: 09.10.2012
Сообщений: 15
По умолчанию ActiveX. Callback в JavaScript из дочернего потока

Добрый день. Пишу ActiveX компоненту в Visual C++;

Необходимо, что бы из компоненты вызывался метод JavaScript, находящийся на HTML-странице, использующей ActiveX.

то есть:
1) вызываю функцию ActiveX'a из JavaScript.
2) ActiveX отрабатывает, вычисляет нужные значения и вызывает функцию JavaScript.

так же необходимо, что бы вычисления и CallBack происходили в дочернем потоке исходной компоненты. Это для того, что бы вычисления происходиле в фоновом режиме и возвращались на страницу.

имеется экспортируемая функция вида:

Код:
STDMETHODIMP Cfirst::testf(VARIANT callbackf)
{	

	msg_struct p;
	
	CComDispatchDriver pObj = V_DISPATCH(&callbackf);

	p.pObjr = pObj;

	boost::thread(f1,p);
	
	return S_OK;

}
и функция вычислений:

Код:
DWORD __stdcall f1(msg_struct param){


	CComDispatchDriver pObj = param.pObjr;


	CComVariant param1 = "Hello world from DLL3 =)";

	HRESULT res = pObj.Invoke1((DISPID)DISPID_VALUE,&param1);

	ofstream f("C:\\test\\out.txt");

	f << hex << res;

	return 0;
}
структура msg_struct

Код:
struct msg_struct {
	
	CComDispatchDriver pObjr;
};
вызов из JavaScript происходит вот так:

Код:
<object id="test" classid="CLSID:A2CFBF35-B953-4BE6-A31C-422FA04A932A" style="display: none;"></object>


	function pAlert(t) {
		alert(t);
	}
	
	function test() {
		var d = document.getElementById("test");
			
		d.testf(pAlert);
	}
Так вот, если запускать функцию f1 напрямую ( то есть вместо boost::thread(f1,p); писать просто f1(p) ), то все хорошо. Компонента запускает pAlert на исходной странице.

Но если запускать ее из потока, то Invoke1 уходит как будто в никуда.
Результат выполнения HRESULT res = pObj.Invoke1((DISPID)DISPID_VALUE,&param1) есть 8000ffff (Unexpected).

Не могу понять, почему так происходит. Есть идеи?
DRFRIMEN вне форума Ответить с цитированием
Старый 09.10.2012, 19:25   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Если пишете COM компоненты, то вы должны быть знакомы с threading моделями COM-а. Похоже у вас apartment модель в этой модели нельзя вызывать медоды объекта созданным одним потоком из другого потока. В рабочем потоке хоть OleInitialize / CoInitialize вызваны?
waleri вне форума Ответить с цитированием
Старый 10.10.2012, 09:00   #3
DRFRIMEN
Пользователь
 
Регистрация: 09.10.2012
Сообщений: 15
По умолчанию

Можно ли немного поподробнее?
Или источник, где можно об этом почитать в доступном виде.
DRFRIMEN вне форума Ответить с цитированием
Старый 10.10.2012, 13:02   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

О чем? Оb OleInitialize или о COM threading model?
waleri вне форума Ответить с цитированием
Старый 10.10.2012, 13:34   #5
DRFRIMEN
Пользователь
 
Регистрация: 09.10.2012
Сообщений: 15
По умолчанию

о COM threading model. Я так понимаю если все так, как вы говорите (т.е. модель не позволяет делать вызовы из соседнего потока), то проблема не решаема?
DRFRIMEN вне форума Ответить с цитированием
Старый 10.10.2012, 16:22   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Почему нерешаема, решаема... Надо заставить вызвать Invoke из "нужного" потока... Есть два способа - либо сами это делаете, скажем создав скрытое окно в основном потоке и послав туда сообщение, либо использоват COM marshalling, что по существу сделает то же самое но более универсально (но и сложнее).

А про модели - вот читайте:
http://blogs.msdn.com/b/larryosterma...28/122240.aspx
http://msdn.microsoft.com/en-us/library/ms809971.aspx
waleri вне форума Ответить с цитированием
Старый 11.10.2012, 11:09   #7
DRFRIMEN
Пользователь
 
Регистрация: 09.10.2012
Сообщений: 15
По умолчанию

никак не могу понять, что есть маршалинг и с чем его едят))
Понимаю что это упаковка какого либо объекта для передачи между тредами, но как это реализуется в упор не понимаю.
Мне бы хотя бы небольшой рабочий пример, что бы было от чего оттолкнуться.
DRFRIMEN вне форума Ответить с цитированием
Старый 11.10.2012, 14:34   #8
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

http://stackoverflow.com/questions/3...ace-that-was-m

Читайте про CoMarshalInterThreadInterfaceInStre am() и CoGetInterfaceAndReleaseStream()
waleri вне форума Ответить с цитированием
Старый 11.10.2012, 14:52   #9
DRFRIMEN
Пользователь
 
Регистрация: 09.10.2012
Сообщений: 15
По умолчанию

Да, спасибо))) уже сам наткнулся на них.
Даже заработало=)))) Не совсем уверен что правильно пользуюсь данной технологией но работает))) спасибо за помощь =)
DRFRIMEN вне форума Ответить с цитированием
Старый 11.10.2012, 15:51   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Главное не ошибится в вызове Release()
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Должно быть 3 потока. А диспетчер задач показывает, что потока создано 2 BEL9ILLI Общие вопросы Delphi 3 06.12.2011 20:26
Как узнать номер потока из самого потока? GaMeSTeR Помощь студентам 0 03.12.2010 09:50
вызов callback Vistar Общие вопросы .NET 9 24.10.2010 14:49
Отключение ActiveX при использовании JavaScript POPOV JavaScript, Ajax 2 02.07.2009 15:47
Callback Wolfheart Win Api 12 02.06.2007 23:13