powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
23 сообщений из 23, страница 1 из 1
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
    #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
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
    #39355885
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eolt,

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Можно, если вызов стоит в методе соответствующего класса или его потомка.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
    #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
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
    #39356362
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovEoltНо тем не менее, метод вызывается. В отладчике я попадаю в CCoEngine::my_event когда его
вызывает сишная DLL.

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


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

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


ну, я невнимательно читал, да.
ладно.
...
Рейтинг: 0 / 0
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
    #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
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
    #39357411
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eolt, прототип и описание push_callback_function покажите
...
Рейтинг: 0 / 0
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
    #39357436
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone,

Код: plaintext
1.
extern int push_callback_function(int *hwnd, int ptr_function, int args);
...
Рейтинг: 0 / 0
Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
    #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
23 сообщений из 23, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Крашится при выходе из метода класса, вызванного по-указателю внешней библиотекой
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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