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

2

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

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

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

Как я могу указать общую библиотеку, которая напрямую не вызывается кодом С#, так что 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 - это моя общая библиотека, которая служит в качестве прокладки между приложением С# и libexif.)

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

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

Вы уверены, что неуправляемый libexif-wrapper можно найти в Переменная среды LD_LIBRARY_PATH?

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

Теги:
shared-libraries
mono

2 ответа

2
Лучший ответ

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

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

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

  • 0
    Сегодня я тщательно проверил ваше решение, используя Code :: Blocks 16.11, и все еще получаю ошибку времени выполнения / usr / bin / mono: ошибка поиска символов: /home/venkat/DevelopmentX64/SmartCamXi_Hybrid_Linux/Debug/libDataServerLib64.so: неопределенный символ: _Z15ciIPxKOpen
2

Я смущен тем, почему вам нужно -lc, но, возможно, это странная особенность...

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

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

  • 0
    Да, спасибо обоим. Добавление -lexif к команде link для моей библиотеки shim решает проблему. Выясняется, что -lc не требуется. Это было частью примера, который я скопировал (и я его копировал по-рабски). Устранение этого, похоже, не вызовет никаких затруднений ни для моего приложения C ++ test, ни для моего приложения C # test.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню