Вопрос

I wrote a simple program to test if xdotool can fulfill my requirements. (Well, not really. My first step is to make sure if I can make calls into the xdotool library.)

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

using namespace std;

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

However, when I compile this with g++ -o a main.cpp libxdo.a -lXtst -lX11 -lXinerama -I ../test/xdotool-2.20110530.1, I get the following error message:

/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

I didn't use the development packages from apt-get install because it installs a dynamic library. So, I did a apt-get source and built the library myself. I verified that xdo_version and xdo_new are defined functions in the static library by performing the following commands:

$ 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

If I am not mistaken, the T besides the symbol's name means that the function is defined.

In conclusion, I'm trying to get the above C++ snippet to compile successfully and statically linking against xdotool but encountered some errors as stated above.

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

Решение

Hint: if the linker shows the signature of a function, then it knows the signature of that function. What does this mean? It means that it has been somehow encoded in the function name at compilation time, i. e. you are the victim of C++ name mangling.

It seems that the xdo.h header doesn't contain safeguards for the case when the C code is compiled as C++. Declare the functions as extern "C" manually for yourself, then recompile, and it will work.

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

Here is some guidance in using dynamic library on g++, from coding till running.

Application code 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;
}

Function code libtest.cpp

#include <iostream>

using namespace std;

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

Building .so file libtest.so

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

Building application main

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

Running application set environmental variable

@bash: export LD_LIBRARY_PATH=:$LD_LIBRARY_PATH

@tcsh: setenv LD_LIBRARY_PATH :$LD_LIBRARY_PATH

Run it!!!

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