簡體   English   中英

Mono p/invoke 中的“未定義符號”使用行為不端的共享 C 庫

[英]“undefined symbol” in Mono p/invoke using misbehaving shared C library

庫 liba 定義了某一個 function f。 在編寫使用 function f 的 C 程序時,除非我在編譯命令中添加 -lb,否則編譯將無法完成,即使我在 Z0D61F8370CAD1D3DE412F80B84D14 代碼中沒有直接引用 libb 中的任何內容。 但是,使用 p/invoke,我沒有鏈接到庫 b 的選項,當我從我的 C# 代碼中調用 function 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。 有沒有辦法解決這個問題?

在到達從 liba 調用 p/invoke 的代碼之前,您還可以從 libb 中 DllImport function:這也會導致 libb 在進程中加載。

這是一個糟糕的解決方案,但在這種情況下它可能是最好的:運行生成的 mono 二進制文件

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM