“未定义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。有什么办法可以解决这个问题吗?

“未定义symbol"在Mono p/调用使用不当的共享C库

您还可以在到达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();
            }
    }