Какова настоящая подпись конструктора C ++ после компиляции - PullRequest
2 голосов
/ 08 октября 2011

Что такое действительная подпись конструктора в C ++?

Справочная информация: я пытаюсь подключить внутренние функции библиотеки DLL.У меня есть файлы pdb-Debug, и я смог получить точное местоположение функции, включая ее недокументированное имя.Функция выглядит так:

protected: __cdecl ClassName::ClassName(bool * __ptr64) __ptr64

Так что это, очевидно, конструктор.Я пробовал функцию void (void * pThisPointer, bool * pBoolPointer), но, поскольку программа падает после простой переадресации вызова (другие функции работают нормально таким образом), я предполагаю, что моя подпись неверна.

Знаете ли выкакую подпись использовать для конструктора (который, скорее всего, не является виртуальным)?Или у вас есть другие идеи, что может пойти не так?

РЕДАКТИРОВАТЬ: я использую x64 и компилятор Visual Studio 2010, целевой компилятор должен быть что-то вроде компилятора Visual Studio, поскольку это Microsoft DLL.

Ответы [ 3 ]

1 голос
/ 10 октября 2011

Самый простой способ - посмотреть на разборку фактического конструктора и посмотреть, к чему он обращается. Обычное соглашение с MSVC (и другими компиляторами) - передавать this в качестве скрытого первого параметра. Обычно это делается с соглашением __thiscall (т.е. в ecx на x86), но на x64 существует только одно соглашение, поэтому __thiscall такой же как __cdecl или __stdcall.

Однако другое, не очень известное соглашение MSVC заключается в том, что конструкторы должны возвращать указатель this . Я подозреваю, что именно это и стало причиной вашего крушения.

Это, вероятно, не очень актуально здесь, но взгляните на мою статью о внутренностях MSVC C ++. Описывает реализацию x86, но многое применимо

1 голос
/ 08 октября 2011

Вы не можете вызвать конструктор напрямую.Что касается C ++, конструкторы не имеют имени.Другими словами, вы не можете вызывать конструкторы.Многие компиляторы создают две или даже три разные функции.Которому вы должны позвонить?

Ответ - ни один из них.Вы не можете и не должны пытаться вызывать конструктор непосредственно из своего кода.

0 голосов
/ 08 октября 2011

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

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

Чтобы выполнить обратное проектирование конструкции объекта, вы должны посмотреть на код, генерируемый в месте, где объект создается с использованием этого конструктора.

...