Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой / 23 сообщений из 23, страница 1 из 1
28.11.2016, 11:08
    #39355799
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
В методе message вызываю сишную библиотеку в DLL и передаю ей указатель на метод my_event.
Чтобы при наступлении определенного события, сишный код мог вызвать метод класса CCoEngine.
В результате my_event вызывается, но при выходе из метода код крашится.

Как тут все сделать правильно?


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
STDMETHODIMP  CCoEngine::my_event() {
  .....
	return S_OK;
}

STDMETHODIMP CCoEngine::message()
{   
     ...	
     push_callback_function(hwnd, (callback_function)(CCoEngine::my_event()), 2);

	return S_OK;
}
    
...
Рейтинг: 0 / 0
28.11.2016, 12:46
    #39355885
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Eolt,

CCoEngine::my_event должен быть static
...
Рейтинг: 0 / 0
28.11.2016, 12:54
    #39355889
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Siemargl,

К сожалению нет :( CCoEngine::my_event вызывает другие методы класса CCoEngine, и поэтому он не может быть статическим.
Как мне кажется, решение есть тут: http://rsdn.org/article/cpp/fastdelegate.xml#E4H
Но знаний как применить это к моей ситуации не хватает.
...
Рейтинг: 0 / 0
28.11.2016, 13:37
    #39355926
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Eolt, к сожалению, да
dll на Си никак не может вызвать метод объекта ввиду отсутствия в Си концепции объекта
...
Рейтинг: 0 / 0
28.11.2016, 13:40
    #39355928
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
EoltCCoEngine::my_event вызывает другие методы класса CCoEngine, и поэтому он не может быть
статическим.

Поэтому его нельзя использовать как callback. Логика!

Обычно функции, в которые передаются коллбэки имеют дополнительный параметр-указатель, в
который и передают указатель на объект. А в самом коллбэке этот указатель используют чтобы
вызвать метод объекта.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2016, 13:43
    #39355930
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Eolt(callback_function)(CCoEngine::my_event())
Кстати, этим принудительным приведением типа ты замаскировал грубый баг: использование
результата вызова функции вместо адреса функции.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2016, 13:52
    #39355939
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Barlonedll на Си никак не может вызвать метод объекта ввиду отсутствия в Си концепции объекта
Ничего страшного, COM объект в С может быть представлен соответствующей структурой
...
Рейтинг: 0 / 0
28.11.2016, 13:59
    #39355945
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
BarloneEolt, к сожалению, да
dll на Си никак не может вызвать метод объекта ввиду отсутствия в Си концепции объекта

Но тем не менее, метод вызывается. В отладчике я попадаю в CCoEngine::my_event когда его вызывает сишная DLL.
Понятно, что видимо параметры в стеке не правильно расположены, или соглашение вызова не то.
Как я думаю проблема в этом. И возможно каким-то "грязным хаком" ее удастся решить.
...
Рейтинг: 0 / 0
28.11.2016, 14:03
    #39355950
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Eolt, вам уже написали, если у функции регистрации коллбека есть дополнительный параметр - указатель, который потом в колбек передается - туда нужно сложить указатель на объект. Если нет - ну разве что через глобальную переменную...
...
Рейтинг: 0 / 0
28.11.2016, 14:05
    #39355953
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
EoltНо тем не менее, метод вызывается. В отладчике я попадаю в CCoEngine::my_event когда его
вызывает сишная DLL.

Нет. См. выше. Ты в него попадаешь когда он вызывается перед вызовом функции из DLL.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2016, 17:37
    #39356206
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Dimitry SibiryakovEolt(callback_function)(CCoEngine::my_event())
Кстати, этим принудительным приведением типа ты замаскировал грубый баг: использование
результата вызова функции вместо адреса функции.

С чего бы это? Результат возвращается в EAX а не на стеке.

Вкратце - механика такая.
У тебя, ТС, указатель на член-функцию. У которой тип вызова _stdcall и есть неявный параметр (передается через стек) this.

А вызывающая функция, очевидно, хочет что то другое (надо смотреть определение callback_function). В итоге после вызова происходит разбалансировка стека (адрес возврата не там где ожидался).

Грубым приведением к (callback_function) ты обошел контроль компилятора.

Это я пишу из предположения что это x86-32, при x86-64 параметр был вы в регистре RCX, и пока бы не вылетало =)
...
Рейтинг: 0 / 0
28.11.2016, 17:38
    #39356210
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
SiemarglDimitry Sibiryakovпропущено...

Кстати, этим принудительным приведением типа ты замаскировал грубый баг: использование
результата вызова функции вместо адреса функции.

С чего бы это? Результат возвращается в EAX а не на стеке.

А точно - скобочки прозевал. Но это уже еще одна ошибка.
...
Рейтинг: 0 / 0
28.11.2016, 17:42
    #39356216
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
SiemarglУ тебя, ТС, указатель на член-функцию.
Ткни пальцем: в каком месте у него "указатель на член-функцию"?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2016, 18:05
    #39356245
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
SiemarglSiemarglпропущено...

С чего бы это? Результат возвращается в EAX а не на стеке.

А точно - скобочки прозевал. Но это уже еще одна ошибка.
Dimitry SibiryakovSiemarglУ тебя, ТС, указатель на член-функцию.
Ткни пальцем: в каком месте у него "указатель на член-функцию"?

Если посмотреть еще раз внимательнее, то у него там и вызова то нет - там синтаксическая ошибка - нельзя вызвать нестатическую ф-цию без экземпляра. Так что мое первое предложение в силе.
...
Рейтинг: 0 / 0
28.11.2016, 18:19
    #39356260
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Siemarglтам синтаксическая ошибка - нельзя вызвать нестатическую ф-цию без экземпляра.

Можно, если вызов стоит в методе соответствующего класса или его потомка.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.11.2016, 19:58
    #39356335
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Dimitry SibiryakovSiemarglтам синтаксическая ошибка - нельзя вызвать нестатическую ф-цию без экземпляра.

Можно, если вызов стоит в методе соответствующего класса или его потомка.

И правда можно.
Это компилятор насоветовал скобочки при попытке компиляции push_callback_function(hwnd, callback_function(CCoEngine::my_event), 2);

error: invalid use of member function (did you forget the '()' ?)

Вот он виноват.
...
Рейтинг: 0 / 0
28.11.2016, 20:57
    #39356362
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Dimitry SibiryakovEoltНо тем не менее, метод вызывается. В отладчике я попадаю в CCoEngine::my_event когда его
вызывает сишная DLL.

Нет. См. выше. Ты в него попадаешь когда он вызывается перед вызовом функции из DLL.


да попасть то в метод в отладчике можно, вопрос, что далее будет, когда уже пропал...

this левый, либо обращение к неведомой памяти, либо затирка таблицы виртуальных функций, а конец один - GPF. защита памяти, снятие задачи.
...
Рейтинг: 0 / 0
28.11.2016, 21:09
    #39356372
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
MasterZivthis левый
С чего вдруг? Ты вообще пять сообщений выше прочитал или как обычно сгоряча фигню порешь?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
29.11.2016, 13:17
    #39356778
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Dimitry SibiryakovMasterZivthis левый
С чего вдруг? Ты вообще пять сообщений выше прочитал или как обычно сгоряча фигню порешь?


ну, я невнимательно читал, да.
ладно.
...
Рейтинг: 0 / 0
29.11.2016, 16:15
    #39357052
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
template <class T>
class CProxy_IChildEvents : public IConnectionPointImpl<T, &DIID__IChildEvents, CComDynamicUnkArray>
{
	//Warning this class may be recreated by the wizard.
public:
 	HRESULT Event_Alert(BSTR msg)
	{
		 ....
		 ....
		 ....

		return varResult.scode;
	}
};
#endif





Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
class ATL_NO_VTABLE CCoEngine : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CCoEngine, &CLSID_CoEngine>,
	public IConnectionPointContainerImpl<CCoEngine>,
	public IDispatchImpl<IChild, &IID_IChild, &LIBID_JIT64Lib>,
	public CProxy_IChildEvents< CCoEngine >
{
public:
	CCoEngine()
	{
		// Init the private data.
		m_bstrName = L"";
		m_bstrMessage = L"";
		m_Age = L"";
  

	}

 


DECLARE_REGISTRY_RESOURCEID(IDR_COSTATS)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CCoEngine)
	COM_INTERFACE_ENTRY(IChild)
	COM_INTERFACE_ENTRY(IDispatch)
	COM_INTERFACE_ENTRY(IConnectionPointContainer)
	COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()


BEGIN_CONNECTION_POINT_MAP(CCoEngine)
	// This is incorrect... 
	// CONNECTION_POINT_ENTRY(IID__IChildEvents)
	CONNECTION_POINT_ENTRY(DIID__IChildEvents)
END_CONNECTION_POINT_MAP()


// IChild
public:
	
	typedef HRESULT(CProxy_IChildEvents<CCoEngine>::*fn)(BSTR str);
	static  fn functionPtr;

private:
	void GetAMessage();
	CComBSTR m_bstrMessage;
	CComBSTR m_Age;
	CComBSTR m_bstrName;
};





Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
CCoEngine::fn  CCoEngine::functionPtr  = &CProxy_IChildEvents::Event_Alert;

static int dll_event (HANDLE *h) {
{
 
  ... 
  как отсюда вызвать Event_Alert?

}


STDMETHODIMP CCoEngine::message()
{   
     ...	
     push_callback_function(hwnd, (callback_function)dll_event , 2);

	return S_OK;
}



Переделал код с учетом ошибок. dll_event - теперь статический метод и туда приходит событие из DLL.
Теперь мне надо вызвать Event_Alert, чтобы в COM объекте возникло событие и передалось клиенту, который получил бы содержимое переменной msg.
Как это сделать?
...
Рейтинг: 0 / 0
30.11.2016, 08:36
    #39357411
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Eolt, прототип и описание push_callback_function покажите
...
Рейтинг: 0 / 0
30.11.2016, 09:13
    #39357436
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Barlone,

Код: plaintext
1.
extern int push_callback_function(int *hwnd, int ptr_function, int args);
...
Рейтинг: 0 / 0
30.11.2016, 13:31
    #39357617
Eolt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Решил сам

Нужна глобальная переменная:
Код: plaintext
1.
extern CCoEngine* cl= NULL;



статическая переменная в классе CCoEngine
Код: plaintext
1.
2.
	typedef HRESULT(CProxy_IChildEvents<CCoEngine>::*fn)(BSTR str);
	static  fn functionPtr;



в CCoEngine::message() присвоить ей ссылку на объект
Код: plaintext
1.
	cl = this;



А в статическом dll_event вызвать метод объекта по указателю"
Код: plaintext
1.
(cl->*CCoEngine::functionPtr)(L"Привет из статического метода!");



В COM-клиенте событие происходит! УРа!
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой / 23 сообщений из 23, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]