У меня есть библиотека 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)
Вы должны указать зависимость, когда вы связываете библиотеку обертки, например
g++ -shared -Wl,-soname,libexif-wrapper.so.1 -o libexif-wrapper.so.1.0.1 libexif-wrapper.o -lc -lexif
Когда вы это сделаете, динамический компоновщик знает, что libexif-wrapper зависит от libexif и он может разрешать символы при загрузке.
Я смущен тем, почему вам нужно -lc
, но, возможно, это странная особенность...
Работает ли он, если вы добавите -lexif
в ссылку? Кажется, что вы создаете общую библиотеку с символами undefined, но не говорите, откуда должны появляться эти символы. Это действительно полезно иногда - скажем, создание плагина, который использует символ, который, как ожидается, уже предоставлен приложением, загружающим его, - но не то, что вы хотите здесь; Я не вижу, как libdl
(или, тем не менее, Mono загружает библиотеки, может быть, имеет собственную реализацию) будет знать, что ему нужно загрузить libexif.so
для использования в вашей библиотеке.
Надеюсь, вам не нужно делать что-то ужасное, как добавить libexif.so
в архив...