【问题标题】:"undefined symbol" in Mono p/invoke using misbehaving shared C libraryMono p/invoke 中的“未定义符号”使用行为不端的共享 C 库
【发布时间】:2011-05-06 00:20:52
【问题描述】:

库 liba 定义了某个函数 f。在编写使用函数 f 的 C 程序时,除非我在编译命令中添加 -lb,否则编译将不会完成,即使我没有在我的 C 代码中直接引用 libb 中的任何内容。但是,使用 p/invoke,我没有链接到库 b 的选项,当我从 C# 代码中调用函数 f(当然是在 [DllImport("liba")] 之后)时,我得到了符号查找错误:/usr/lib/liba.so:未定义符号:X(X 在 libb 中定义)。 ldd /usr/lib/liba.so 不包含引用 libb 的行。 libb 在 /usr/lib 中。我相信这个问题与Linux, Mono, shared libs and unresolved symbols 基本相同,但与那种情况不同,我无法重新编译 liba。有什么办法可以解决这个问题吗?

【问题讨论】:

    标签: c# mono pinvoke


    【解决方案1】:

    您还可以在到达 p/从 liba 调用的代码之前从 libb 中 DllImport 一个函数:这也会导致 libb 在进程中被加载。

    【讨论】:

    • 我很确定这会起作用,但由于它需要使用你永远不需要的功能,我认为下面的解决方案要好一些。
    【解决方案2】:

    这是一个糟糕的解决方案,但在这种情况下它可能是最好的:使用

    运行生成的单声道二进制文件
    LD_PRELOAD=libb.so ./binary.exe 
    

    避免问题。

    【讨论】:

      【解决方案3】:

      找到了一个很好的通用解决方案,示例如下:

        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();
                  }
          }
      

      【讨论】:

      • 此解决方案不可移植。另请注意,使用我的解决方案,如果 libb 没有合适的函数,您应该能够调用不存在的函数:只需捕获异常即可。与此 dlopen hack 不同,这将适用于所有操作系统。
      • 这不是 Linux 特有的未定义符号错误吗?为什么这是“黑客”?
      • 我刚查了一下:OSX和BSD也有dlopen,Windows这样就不会出现这个问题了。
      猜你喜欢
      • 2011-02-28
      • 2018-04-14
      • 2016-10-16
      • 2011-07-19
      • 1970-01-01
      • 2010-10-17
      • 2012-09-27
      • 2012-01-08
      • 2010-11-09
      相关资源
      最近更新 更多