“未定义symbol"在Mono p/调用使用不当的共享C库
本文关键字:未定义 使用不当 调用 共享 Mono symbol quot | 更新日期: 2023-09-27 17:54:41
Library liba定义了一个特定的函数f。当编写一个使用函数f的C程序时,除非在编译命令中添加-lb,否则编译不会完成,即使我在C代码中没有直接引用lib中的任何内容。然而,使用p/invoke,我没有链接到库b的选项,当我从c#代码中调用函数f(当然是在[DllImport("liba")]之后)时,我得到一个符号查找错误:/usr/lib/liba。so: undefined symbol: X (X在lib中定义)。ldd/usr/lib/liba.所以不包含指向lib的行。lib在/usr/lib中我相信这个问题本质上与Linux, Mono,共享库和未解析的符号相同,但不像在这种情况下,我无法重新编译liba。有什么办法可以解决这个问题吗?
您还可以在到达p/从liba调用的代码之前从libb中DllImport一个函数:这将导致libb也在进程中被加载。
这是一个糟糕的解决方案,但在以下情况下,它可能是最好的解决方案:使用
运行生成的单二进制文件LD_PRELOAD=libb.so ./binary.exe
避免了这个问题
找到了一个很好的通用解决方案,示例如下:
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();
}
}