views:

288

answers:

5

Running the whole thing will result in the following error:

Cannot open library "./libexamplefilter.so" ./libexamplefilter.so: undefined symbol: _ZTI10BaseFilter

Since the code is pretty small and understandable you should be able to understand it right away. Anyone a clue what is wrong?

Should I make rather declare create() as extern "C" void* create(void); and cast the void pointer afterwards instead of directly trying to link c++ symbols?

Next Step

after using -Wl,-export-dynamic, it tells me:

Cannot load library symbols "./libexamplefilter.so" ./libexamplefilter.so: undefined symbol: create

Uh, do I have to give a mangled c++-name there instead of "dlsym(handle, "create")". Probably. Is there a elegant way to do this?

The answer is declaring create() extern "C" ... create .... This works perfectly well. Problem solved. Thanks for your help and patience.

+3  A: 

You need to use the linker option "export-dynamic" when compiling your main executable.

Normally, the main executable won't export its symbols for use by the dynamic linker (unless the symbol is used by some shared library participating in the link), which means that if your library calls back into the main exe, it will fail to load.

This happens implicitly when you try to subclass a class with virtual methods and in some other cases. If you try to do this, it's a fail.

So when linking your main program, add -Wl,-export-dynamic, it'll just work.

MarkR
The linker error clearly shows an undefined symbol in libexamplefilter.so (from a class in that library), not in the executable, so it can't be this.
Troubadour
No it doesn't, it shows an undefined symbol *while loading the library*. The fix is to compile the main executable differently.
MarkR
It mentions the library twice. Once to say it can't load it and them a second time as a prefix to the missing symbol. If that doesn't imply that the symbol is missing in the named library then that's the stupidest error message I've ever seen. I'm not convinced.
Troubadour
The ld.so linker doesn't search for specific symbols in specific libraries. It just means that there's a reference in libexamplefilter.so to that symbol, which can't be found anywhere. That symbol probably is in the main exe, but isn't exported so the linker isn't picking it up. Add -Wl,-export-dynamic and it will work. Really.
MarkR
Is there a downside to "exporting all symbols" ?
Ronny
Well, you get them exported, so you can have conflicts with those in libraries. Also OEMs can call any function that they know the prototype of and is not declared static.
MarkR
@MarkR: Okay, thanks for clearing that up. I stand corrected.
Troubadour
+1  A: 

I ran into this in my exploration of plugin architectures. Your error is not in your main, it's in how you've linked libexamplefilter.so . Unfortunately, I don't have the code (or the memory!) to tell you exactly how to solve it, but I think you'll need to have your BaseFilter class declared in a separate .so, and link both libexamplefilter and your application against that .so.

Harper Shelby
+2  A: 

It could be a mismatch in visibility of the _ZTI10BaseFilter symbol (which is the type-info for the class) between your .so and the application. What do you get if you run

nm <target> | grep _ZTI10BaseFilter

on each target that includes BaseFilter i.e. your dynamic libraries and executable?

Troubadour
nm videocapture | grep _ZTI10BaseFilter08077f18 V _ZTI10BaseFilternm libexamplefilter.so | grep _ZTI10BaseFilter U _ZTI10BaseFilter
Ronny
Oh well, it's not that then.
Troubadour
+1  A: 

Should I rather declare create() as extern "C" void* create(void); and cast the void pointer afterwards instead of directly trying to link c++ symbols?

Personally I would recommend this, even if it's not the real problem. Name mangling is pretty standard nowadays among the UNIX-like OSes -- what with the Intel ABI and all -- but it's not truly standard, and Windows uses a different name mangling scheme (so porting the app to Windows would require changing those strings), and I'm not sure if OS X is on board (so porting to OS X may require changing those strings).

Max Lybbert
A: 

I found a mini tutorial on this topic

Ronny