Я использую определенные инструменты GNU, то есть компилятор GNU C ++ (G ++) и линкер GNU (LD) для создания файла общей библиотеки (.so), а также в бинарный исполняемый файл файл.
Бинарный исполняемый файл использует функцию DLOPEN
, чтобы динамически загрузить файл общего библиотека во время выполнения. В дополнение к этому, файл общего библиотеки
Нужно вызывать определенный метод класса (называемый ToolboxManager :: RegisterToolox
), который определяется в двоичном исполняемости. Это размещено путем принудительного бинара
Исполняемый для экспорта метода класса, который, в свою очередь, выполняется по времени связи, связывая двоичный исполняемый с помощью следующих параметров командной строки;
-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt
где файл $ {TOP_SRCDIR} /Dynamic_symbol_table.txt
содержит следующие Содержание;
{
extern "C++"
{
"ToolboxManager::registerToolbox*";
};
};
Обратите внимание на использование звездочки (*) в файле, чтобы заставить линкер экспортировать все символы, которые начинаются с ToolboxManager :: RegisterToolox
.
Когда я запускаю утилиту GNU NM ( NM -C -G ./a.out
) на полученном двоичном исполняемости, он отображает следующую информацию о вышеупомянутом методе класса;
08053da0 T ToolboxManager::registerToolbox
(
std::string&,
std::string&,
std::map
<
std::string,
Factory_DSPB_Base*,
std::less
<
std::string
>,
std::allocator
<
std::pair
<
std::string const,
Factory_DSPB_Base*
>
>
>&
)
Или, если утилита NM вызывается как указано выше, но на этот раз без использования коммутатора командной строки -c;
08053da0 T _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
до сих пор это выглядит нормально. «T» перед определением метода класса ToolboxManager :: RegisterToolox
, обозначает, что метод находится в разделе «Текст / код» файла.
Аналогично, если я запускаю утилиту NM ( NM -C -G ./toolbox.so
) в файле общего библиотека, он отображает следующую информацию о том же вышеупомянутом классе
Метод;
U ToolboxManager::registerToolbox
(
std::string&,
std::string&,
std::map
<
std::string,
Factory_DSPB_Base*,
std::less
<
std::string
>,
std::allocator
<
std::pair
<
std::string const,
Factory_DSPB_Base*
>
>
>&
)
Это также выглядит нормально. «U» перед определением метода класса ToolboxManager :: RegisterToolbox
, обозначает, что метод не определен в файле общего библиотеки.
Тем не менее, проблема возникает, когда я запускаю бинарную передачу от командной строки, и эта проблема приводит к отображению следующего сообщения об ошибке;
./toolbox.so: undefined symbol: _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
Имя метода Mangled класса, которое появляется в этом сообщении выполнения, как Первый из двух строк. Для целей сравнения, имя метода Mangled класса сверху (и который генерировал с использованием команды NM -G
), отображается ниже как второй из двух строк;
_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
Как видно, два потрясенных имена идентичны. Следовательно, я не могу понять, почему неопределенный символ не может быть разрешен во время выполнения.
Я затем повторно связывал бинарный исполняемый файл, однако на этот раз я заменил следующую команду «ссылка»;
-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt
с этим;
-Wl,--export-dynamic
- Экспорт-динамичный вариант
Опция линкера Указывает на GNU Линкер, чтобы добавить все символы в таблицу динамического символа.
Если затем снова запустите файл бинарный исполняемый. На этот раз он выполнен Правильно и вызов функции DLOPEN не привел к неопределенному ошибке символа. Это имеет мне совершенно озадаченное, как выглядит как будто символ экспортируется правильно в исходной версии двоичного исполняемого исполняемого файла. Кто-нибудь может увидеть эту проблему здесь? Любая помощь была бы небещено ценится.
заранее спасибо.