Неопределенные ссылки после связывания со статической библиотекой

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

#include <xdo.h>
#include <iostream>

using namespace std;

int main(){
    cout << xdo_version() << endl;
    xdo_new(NULL);
    return 0;
}

Тем не менее, когда я собираю это с g++ -o a main.cpp libxdo.a -lXtst -lX11 -lXinerama -I ../test/xdotool-2.20110530.1Я получаю следующее сообщение об ошибке:

/tmp/ccW95RQx.o: In function `main':
main.cpp:(.text+0x5): undefined reference to `xdo_version()'
main.cpp:(.text+0x29): undefined reference to `xdo_new(char*)'
collect2: error: ld returned 1 exit status
make: *** [sendkey] Error 1

Я не использовал пакеты разработки из apt-get install, потому что он устанавливает динамическую библиотеку. Итак, я сделал apt-get source и сам собрал библиотеку. Я проверил, что xdo_version и xdo_new являются определенными функциями в статической библиотеке, выполнив следующие команды:

$ nm libxdo.a | grep xdo_version
00000000000002b0 T xdo_version
$ nm libxdo.a | grep xdo_new
0000000000004070 T xdo_new
0000000000003c90 T xdo_new_with_opened_display

Если я не ошибаюсь, T кроме того, имя символа означает, что функция определена.

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

2 ответа

Решение

Подсказка: если компоновщик показывает сигнатуру функции, то он знает сигнатуру этой функции. Что это значит? Это означает, что он был каким-то образом закодирован в имени функции во время компиляции, т.е. вы стали жертвой искажения имени в C++.

Кажется, что xdo.h Заголовок не содержит мер безопасности для случая, когда код C компилируется как C++. Объявите функции как extern "C" вручную для себя, потом перекомпилируй, и все заработает.

Вот несколько советов по использованию динамической библиотеки на g++, от кодирования до запуска.

Код приложения main.cpp

#include <iostream>

using namespace std;

extern "C" int funct(const int in);

int main(int argc, char** args){

    cout << "test message " << funct(5) << endl;
    return 0;
}

Код функции libtest.cpp

#include <iostream>

using namespace std;

extern "C" int funct(const int in){
    return in*in;
}

Сборка.so файла libtest.so

g++ -fPIC -c libtest.cpp
g++ -shared -o libtest.so libtest.o

Основное приложение здания

g++ -L. main.cpp -o main -ltest

Запущенное приложение устанавливает переменную среды

@bash: экспорт LD_LIBRARY_PATH =: $ LD_LIBRARY_PATH

@tcsh: setenv LD_LIBRARY_PATH: $ LD_LIBRARY_PATH

Запустить его!!!

./main
test message 25
Другие вопросы по тегам