“未定义的符号”在 Mono p/invoke 中使用行为不当的共享 C 库

发布于 2024-11-05 04:10:24 字数 458 浏览 4 评论 0原文

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、共享库和未解析的符号相同,但与那种情况不同的是,我无法重新编译 liba。有什么办法可以解决这个问题吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怎会甘心 2024-11-12 04:10:24

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

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.

打小就很酷 2024-11-12 04:10:24

这是一个糟糕的解决方案,但在这种情况下它可能是最好的解决方案:运行生成的单二进制文件

LD_PRELOAD=libb.so ./binary.exe 

可以避免该问题。

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.

栀子花开つ 2024-11-12 04:10:24

找到了一个很好的通用解决方案,如下面的代码所示:

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

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();
            }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文