Reputation: 5435
Library liba defines a certain function f. When writing a C program that uses function f, compilation will not complete unless I add -lb to the compilation command, even though I don't refer to anything from libb directly in my C code. Using p/invoke, however, I don't have the option of linking to library b and when I call function f (after a [DllImport("liba")], of course) from within my C# code I get a symbol lookup error: /usr/lib/liba.so: undefined symbol: X (X is defined within libb). ldd /usr/lib/liba.so does not contain a row referring to libb. libb is in /usr/lib. I believe this question is essentially the same as Linux, Mono, shared libs and unresolved symbols, but unlike in that case I cannot recompile liba. Is there any way to resolve this problem?
Upvotes: 1
Views: 2120
Reputation: 5435
Found a good general solution, exemplified in the code below:
class MainClass
{
//Constants from /usr/include/bits/dlfcn.h
private const int RTLD_LAZY = 0x00001; //Only resolve symbols as needed
private const int RTLD_GLOBAL = 0x00100; //Make symbols available to libraries loaded later
[DllImport("dl")]
private static extern IntPtr dlopen (string file, int mode);
[DllImport("a")]
private static extern void f ();
public static void Main (string[] args)
{
//Load libb. RTLD_LAZY could be replaced with RTLD_NOW, but
//RTLD_GLOBAL is essential
dlopen("libb.so", RTLD_LAZY|RTLD_GLOBAL);
//Call f(), no unresolved symbol problem!
f();
}
}
Upvotes: 0
Reputation: 3973
You can also DllImport a function from libb before reaching the code that p/invokes from liba: this will cause libb to be loaded in the process as well.
Upvotes: 2
Reputation: 5435
This is a poor solution, but it might be the best possible under the circumstances: running the resulting mono binary with
LD_PRELOAD=libb.so ./binary.exe
avoids the problem.
Upvotes: 1