Linux, Mono, общие библиотеки и неразрешенные символы

У меня есть библиотека прокладок (общая, C++), которая вызывает функции из другой общей библиотеки (libexif) и представляет собой простой интерфейс для C# для вызовов Platform Invoke. (То есть программа C# использует PInvoke для вызова моей пользовательской общей библиотеки, которая, в свою очередь, вызывает другую общую библиотеку.)

В Windows моя пользовательская общая библиотека связывается с общей библиотекой, когда моя пользовательская библиотека связывается, и когда приложение C# выполняется, все символы разрешаются.

В Linux связывание моей общей библиотеки не связывает другую общую библиотеку. При использовании драйвера C++ я указываю другую библиотеку, когда приложение компонуется, и в это время разрешаются все символы. Однако, когда я пытаюсь вызвать свою общую библиотеку из программы C# (скомпилированной с использованием моно), символы в другой общей библиотеке не разрешаются. Я пытался использовать переменную MONO_PATH, чтобы указать другую библиотеку, но, похоже, это не имеет значения. Я также пытался указать неразрешенную функцию в операторе DLLimport, но это, похоже, тоже не помогает.

Как я могу указать разделяемую библиотеку, которая не вызывается напрямую кодом C#, чтобы mono/cli нашел ее во время выполнения?

Я использую следующие команды для создания общей библиотеки:

g++ -fPIC -g -c -Wall  libexif-wrapper.cpp
g++ -shared -Wl,-soname,libexif-wrapper.so.1     -o libexif-wrapper.so.1.0.1 libexif-wrapper.o -lc
ar rcs libexif-wrapper.a libexif-wrapper.so.1

И следующая командная строка для компиляции моего драйвера С#:

mcs -unsafe -define:LINUX Test-libexif-wrapper.cs

При выполнении я получаю сообщение об ошибке, что символ, используемый моей общей библиотекой, не найден:

/usr/bin/cli: symbol lookup error: ../../../C/libexif-wrapper/libexif-wrapper/libexif-wrapper.so.1: undefined symbol: exif_data_new_from_file

(libexif-wrapper — это моя общая библиотека, которая служит прокладкой между приложением C# и libexif.)

Я не смог понять, как это решить. Мы ценим любые предложения.

редактировать: Чтобы ответить на вопрос:

Вы уверены, что неуправляемую libexif-оболочку можно найти в переменной окружения LD_LIBRARY_PATH?

На самом деле это не так. Вместо этого я создал путь в DLLImport, чтобы он указывал прямо на него. Среда выполнения находит его, поскольку сообщает путь к нему в сообщении об ошибке выше. Кроме того, отсутствующий символ не вызывается программой C#, а одна из функций в моей общей библиотеке вызывает функцию, которая затем не найдена. (спасибо - Хэнк)


person HankB    schedule 02.04.2009    source источник


Ответы (2)


Вы должны указать зависимость, когда вы связываете библиотеку-оболочку, например

g++ -shared -Wl,-soname,libexif-wrapper.so.1 -o libexif-wrapper.so.1.0.1 libexif-wrapper.o -lc -lexif

Когда вы делаете это, динамический компоновщик знает, что libexif-wrapper зависит от libexif и может разрешать символы при загрузке.

person lothar    schedule 02.04.2009
comment
Сегодня я тщательно протестировал ваше решение, используя Code::Blocks 16.11, и все еще получаю ошибку времени выполнения /usr/bin/mono: ошибка поиска символа: /home/venkat/DevelopmentX64/SmartCamXi_Hybrid_Linux/Debug/libDataServerLib64.so: неопределенный символ: _Z15ciIPC_OpenMutexPKc - person Frank; 11.04.2016

Я не понимаю, зачем вам нужен -lc, но, возможно, это странность Mono...

Будет ли работать, если вы добавите -lexif в команду ссылки? Похоже, вы создаете общую библиотеку с неопределенными символами, но не указываете откуда эти символы. На самом деле иногда это бывает полезно — скажем, создание плагина, который использует символ, который, как ожидается, уже предоставлен загружающим его приложением, — но не то, что вам нужно здесь; Я не понимаю, как libdl (или, тем не менее, Mono загружает библиотеки, может быть, у него есть собственная реализация) узнает, что ему нужно загрузить libexif.so для использования в вашей библиотеке.

Надеюсь, вам не придется делать что-то ужасное, например, добавлять libexif.so в архив...

person ephemient    schedule 02.04.2009
comment
Да, спасибо обоим. Добавление -lexif к команде ссылки для моей библиотеки прокладок решает проблему. Оказывается, -lc не требуется. Это была часть примера, который я скопировал (и я скопировал его рабски). Устранение этого, кажется, не вызывает затруднений ни для моего тестового приложения C++, ни для моего тестового приложения C#. - person HankB; 03.04.2009