![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Proxin |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
Здравствуйте, есть следующий класс
и нужно вызвать виртуальную функцию по указателю, который сохранятся вот так:
как вызвать func из объекта obj ? вот так:
выдаёт acess violation. как получить доступ к действительному адресу функции? если объявить функцию без virtual, вышеприведённый код работает без проблем. Это сообщение отредактировал(а) Proxin - 12.10.2015, 02:35 |
||||||
|
|||||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 11 Всего: 45 |
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Proxin |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
Точно, ошибся. У меня в коде так как у вас, тут по памяти писал, но ошибка с волайшоном всё равно присутствует.
|
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 11 Всего: 45 |
А что у Вас за компилятор?
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Proxin |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
vc++ 6.0
|
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
А есть ли по настоящему необходимость в указателе на вирутальную функцию?
Я в своё время посмотрел на ассемблерный код, генерируемый в таких случаях C++Builder (код правильный, рассматривает все мозможые случаи вызова, но один вызов может занять килобайт кода) и делаю обычно так:
|
|||
|
||||
Proxin |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
math64, можно попробовать и Ваш способ, но меня интересует, как вызвать именно виртуальную функцию, без хаков. Или это невозможно?
|
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Вероятно, в Microsoft в VC++6.0 решили запретить указатели на виртуальные функции, чтобы не генерить при какждом использовании указателя на функцию класса килобайтный код (заранее не известно - виртульная она или нет, при каждом вызове нужно проверять). Возможно, в более новых компиляторах ситуация другая.
В C++Builder, как альтернатива, есть 8 байтный указатель на функцию, включающий в себя указатель на класс и обычный указатель на функцию (при этом при вызове проверять на вируальность не надо), но это нестандартное расширение языка. Добавлено через 7 минут и 41 секунду Вот ссылка на MSDN: https://msdn.microsoft.com/en-us/library/f2wbycwh.aspx
|
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 11 Всего: 45 |
Попробовал на нём аналогичный код без всяких ключей компиляции:
Возможно, какой-то ключ компиляции и вызывает проблемы с acess violation. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
у меня в VC 6.0 всё работает.
Добавлено через 48 секунд когда писал не видел последний ответ от feodorv, |
||||
|
|||||
Proxin |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
А может ли ошибка возникать из-за того, что это всё находится в библиотеке, которая подключается динамически через собственный загрузчик ( впрочем, через LoadLibrary тоже глюк присутствует)?
|
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Указатель на функцию передаётся в библиотеку?
Если библиотека и основная программа откомпилирована с разными ключами, влияющими на применение указателей на виртульный метод класса - то да. И не важно, как грузится библиотека - обычной линковкой или через LoadLibrary. Формат указателя если разрешены указатели на виртульный метод класса или нет - разные. Да, ещё класс нужно объявлять типа class __declspec(dllimport/dllexport) A { ... }; |
|||
|
||||
Proxin |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
Всем спасибо, у меня оказалась пролема в том, что указатель сохранялся как __cdecl, оказывается.
А можно ли как-нибудь указать конвенцию вызова методов класса как __cdecl? или как-нибудь сохранять в указатель одного типа классовые функции с различными параметрами? у меня сейчас вот так
выдаёт ошибку о неправильном стёке ( The value of ESP was not properly saved across a function call. This is usually a result of calling a function pointer declared with a different calling convention. ) а вот так:
всё работает, но мне нужно, чтобы в указатель типа cfnc можно было сохранять и вызывать функции с любым числом любых параметров. Это сообщение отредактировал(а) Proxin - 15.10.2015, 17:53 |
||||
|
|||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 11 Всего: 45 |
Попробовал, работает:
Добавлено через 2 минуты и 39 секунд va_end(ap) забыл... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Proxin |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 363 Регистрация: 21.6.2008 Репутация: нет Всего: 3 |
Первый параметр не обязательно будет int или char*, он может быть вообще любым ( например, __int64, который 8 вместо 4, или char, который вообще 1 )
А из-за чего у меня возникает ошибка при cdecl и функции с воообще не определённым числом параметров? Насколько помню, по спецификации typedef-ы с ( ... ) без параметров разрешены, лишь бы было соглашение о вызове правильное. Там же передача всё равно с конца стёка идёт. По крайней пере с обычными функциями, без классов
работает же, или я чего-то фундаментального не понимаю? Это сообщение отредактировал(а) Proxin - 16.10.2015, 10:03 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |