«неопределенный символ» в Mono p / invoke с использованием некорректно работающей совместно используемой библиотеки C - PullRequest
0 голосов
/ 05 мая 2011

Библиотека liba определяет определенную функцию f. При написании программы на C, использующей функцию f, компиляция не завершится, если я не добавлю -lb к команде компиляции, даже если я не ссылаюсь на что-либо из libb непосредственно в моем C-коде. Однако, используя p / invoke, у меня нет опции связывания с библиотекой b, и когда я вызываю функцию f (после, конечно, [DllImport ("liba"]]) из моего кода C #, я получаю поиск символов ошибка: /usr/lib/liba.so: неопределенный символ: X (X определен в libb). ldd /usr/lib/liba.so не содержит строки, ссылающейся на libb. libb находится в / usr / lib. Я считаю, что этот вопрос по сути такой же, как Linux, Mono, общие библиотеки и неразрешенные символы , но в отличие от этого случая я не могу перекомпилировать liba. Есть ли способ решить эту проблему?

Ответы [ 3 ]

2 голосов
/ 05 мая 2011

Вы также можете DllImport функции из libb до достижения кода, который p / вызывает из liba: это также приведет к загрузке libb в процессе.

1 голос
/ 05 мая 2011

Это плохое решение, но оно может быть наилучшим из возможных обстоятельств: запуск полученного монофонического двоичного файла с

LD_PRELOAD=libb.so ./binary.exe 

избегает проблемы.

0 голосов
/ 05 мая 2011

Нашли хорошее общее решение, приведенное в коде ниже:

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