Вопрос

в C ++ я могу легко создать указатель на функцию, взяв адрес функции-члена.Однако возможно ли изменить адрес этой локальной функции?

То есть.допустим, у меня есть funcA() и funcB() в одном классе, определенные по-разному.Я хочу изменить адрес funcA() на адрес funcB() таким образом, чтобы во время выполнения вызов funcA() фактически приводил к вызову funcB().Я знаю, это некрасиво, но мне нужно это сделать, спасибо!

Редактировать----------

Предыстория того, что я пытаюсь сделать:

Я надеюсь реализовать модульные тесты для существующей базы кода, некоторые методы в базовом классе, от которого наследуются все мои модули, не являются виртуальными.Мне не разрешено редактировать какой-либо производственный код.Я могу повозиться с процессом сборки и заменить в базовом классе соответствующие методы, установленные в virtual, но я подумал, что предпочел бы использовать подобный взлом (который, как я думал, был возможен).

Кроме того, я интересуюсь этой темой из технического любопытства, поскольку в процессе попыток обойти эту проблему я узнаю довольно много о том, как такие вещи, как генерация кода и поиск функций, работают под капотом, чему у меня не было возможности научиться в школе, поскольку я только что закончил 2 курс университета.Я не уверен, что меня когда-нибудь научат таким вещам в школе, поскольку я занимаюсь компьютерной инженерией, а не CS.

Возвращаясь к теме Методы funcA() и funcB() действительно имеют одинаковую сигнатуру, поэтому проблема в том, что я могу получить адрес функции только с помощью оператора &?Правильно ли я буду сказать, что я не могу изменить адрес функции или поменять местами содержимое по этому адресу без повреждения частей памяти?Будет ли внедрение DLL хорошим подходом для подобной ситуации, если функции экспортируются в dll?

Это было полезно?

Решение

Нет.Функции компилируются в исполняемый файл, и их адрес фиксируется на протяжении всего срока службы программы.

Самая близкая вещь - это виртуальные функции.Приведите нам пример того, чего вы пытаетесь достичь, я обещаю, что есть способ получше.

Другие советы

Это не может быть сделано так, как вы это описываете.Единственный способ изменить цель для статически связанного вызова - это изменить фактический исполняемый код вашей программы.Язык C ++ не имеет функций, которые могли бы этого достичь.

Если вы хотите, чтобы вызовы функций разрешались во время выполнения, вы должны либо использовать явно косвенные вызовы (вызов через указатели на функции), либо использовать языковые функции, основанные на разрешении вызовов во время выполнения (например, виртуальные функции), либо вы можете использовать обычное ветвление со старым добрым if или switch.Что более уместно в вашем случае, зависит от вашей конкретной проблемы.

Технически это может быть возможно для виртуальных функций путем изменения vtable данного типа, но вы, безусловно, не сможете этого сделать, не нарушая стандарт (вызывая неопределенное поведение), и для этого потребуется знание того, как ваш конкретный компилятор обрабатывает vtables.

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

То, что вам нужно, это указатель на функцию, вы можете указать его на funcA или funcB, предполагая, что они имеют одинаковую сигнатуру.

Я совершенно уверен, что это невозможно в чистом C ++.C ++ не является динамическим языком.

Вы не можете делать то, что хотите сделать напрямую.Однако вы можете достичь аналогичного результата с некоторыми немного отличающимися критериями, используя то, с чем вы уже знакомы - указатели на функции.Рассмотреть:

// This type could be whatever you need, including a member function pointer type.
typedef void (*FunctionPointer)();

struct T {
   FunctionPointer Function;
};

Теперь вы можете установить Function участник на любом данном T экземпляр, и вызовите его.Это примерно настолько близко, насколько вы можете разумно приблизиться, и я предполагаю, что, поскольку вы уже знаете об указателях на функции, вы уже знаете об этом решении.

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

Это просто!

Для

во время выполнения вызов funcA() фактически приводит к вызову funcB().

написать funcA() аналогично следующему:

int funcA( int a, int b) {
  return funcB( a, b );
}

:-)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top