Reputation:
I am trying to use a shared library (to which I don't know the source code). However I struggle with linking it into my project. The library contains an API for a camera driver, which is pretty much a bunch of functions thrown together (as far as I can see there is no structure).
The library (and two symlinks to it) are located in /usr/lib and are called
libueye_api64.so.4.72 - the library
libueye_api.so.1 - a symlink pointing to above library
libueye_api.so - another symlink pointing to libueye_api64.so.4.72
there also is a header file located in /usr/include named ueye.h
which is the header file for the library (at least I assume that).
Using the simple example mwe.cpp
#include "ueye.h"
int main()
{
int device_count = 0;
int error_value = is_GetNumberOfCameras(&device_count);
return 0;
}
which I tried to compile (successful) and link, I got the following:
~/Documents/mwe$ g++ -I/usr/include -c mwe.cpp
~/Documents/mwe$ g++ -L/usr/lib -lueye_api mwe.o -o test
mwe.o: In function `main':
mwe.cpp:(.text+0x17): undefined reference to `is_GetNumberOfCameras'
collect2: error: ld returned 1 exit status
Which should mean that either is_GetNumberOfCameras
is not implemented in the library or I have some scoping issue. In any way the linker can't find an implementation for this function (which is part of the API according to the documentation).
I further dumped the list of all symbols in the .so using
readelf -Ws /usr/lib/libueye_api64.so.4.72
which has the symbol I am looking for:
980: 00000000003372b0 5 FUNC GLOBAL DEFAULT 12 is_GetNumberOfCameras
This makes me wonder why I can't find it. Am I including the wrong library? I tried compiling with ueye_api64
but this would just return cannot find library
. So, what am I missing?
Edit: I should also mention, that I am doing this under Linux (Ubuntu 14.04) using gcc, which you probably figured out by now.
Upvotes: 2
Views: 1153
Reputation: 17483
Try to change:
g++ -L/usr/lib -lueye_api mwe.o -o test
To:
g++ mwe.o -o test -L/usr/lib -lueye_api
You can look at this SO discussion to understand why the order is important. The accepted answer gives a great explanation.
The main idea is that the linker checks library to resolve currently unresolved symbols only once when it meets this library in the list of options.
But all options are processed consequently.
So if you put -lueye_api
before mwe.o
linker doesn't know about mwe.o
and, of course, it doesn't try to resolve anything (in fact, he hasn't any symbols to resolve).
From the other side, if you put -lueye_api
after mwe.o
linker firstly add all unresolved symbols from mwe.o
to the list of unresolved symbols and after that resolves all of them using ueye_api
library successfully.
Finally, this is another good discussion that will be helpful for you.
Upvotes: 4