Динамическое связывание и Python SWIG (C ++) работает в C ++, не работает в Python - PullRequest
2 голосов
/ 03 августа 2010

У меня есть библиотека, для которой я создал оболочку Python, используя SWIG.Сама библиотека принимает предоставляемые пользователем функции, которые находятся в файле .so, который динамически связан.На данный момент я имею дело с тем, что я создал сам и сумел заставить динамическое связывание работать ... в C ++.Когда я пытаюсь запустить его в Python, я получаю неопределенные ошибки символов.Это те символы, которые отсутствуют в предоставленном файле .so, но присутствуют в основной программе (по сути, это функции, которые позволяют предоставленному модулю получать доступ к данным из основной программы).

Я неполучить любые ошибки при запуске короткой тестовой программы на C ++, но короткая тестовая программа на python с этой оболочкой (которая работала ранее) не работает.Я не могу придумать объяснения, почему он потерпит неудачу в C ++, а не в Python.Что меня немного беспокоит, так это мысль о том, что C ++ не работает должным образом, но не говорит мне об этом, а питон обнаруживает ошибки, которых нет в C ++.Тем не менее, результат, возвращаемый C ++, является точным, поэтому это кажется маловероятным.

Есть мысли, как это возможно и, следовательно, как я мог это исправить?

Спасибо.

Обновление: Я добавил этот код в начало программы:

import dl
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)

Это избавляет от ошибки времени выполнения, но, к сожалению, позволяет возникать вторая проблема (все еще из-за связывания).Функции, которые вызываются из динамически связанной библиотеки, являющейся частью основной программы, не возвращают правильные значения.Они возвращают 0. Более того, очевидно, что их вообще не запускают.Возникает вопрос: что на самом деле выполняется, почему он отличается от C ++ и как я могу это исправить?

Еще раз спасибо.

Обновление - потенциально более ясное объяснение Python импортирует модуль,это моя библиотека C ++, которая была упакована SWIG.Эта библиотека C ++ использует dlopen и dlsym для получения функций из предоставленного пользователем файла .so.Пользователь предоставил файловые вызовы для функций, которые являются частью библиотеки C ++, чтобы выполнить свою работу.Вызовы функций из файла .so в библиотеку C ++ являются той частью, которая вызывает сбой, то есть они не могут вызвать функцию и просто возвращают 0. Однако эта ошибка происходит только тогда, когда тестовый код написан на python.Тестовый код C ++, который использует библиотеку, работает нормально.

Ответы [ 2 ]

2 голосов
/ 05 августа 2010

Решение состоит в том, чтобы убедиться, что python предварительно загружает основную библиотеку C ++ в глобальной области видимости.Это не очень элегантное решение, и я не хочу его делать, но оно заставляет его работать на данный момент.

После небольшого осмотра здесь и распознавания среды LD_LIBRARY_PATHпеременную, которую я должен устанавливать каждый раз, когда я запускаю терминал, чтобы он мог даже найти основную библиотеку C ++, которая была SWIGed, я заметил переменную среды LD_PRELOAD.После установки в качестве имени файла основной библиотеки C ++ программа работала.

Я подозреваю, что это потому, что она "может использоваться для выборочного переопределения функций в других общих библиотеках".

Если кто-нибудь придетполучить лучший ответ, чем задавать переменные среды, было бы здорово, так как я не уверен, насколько это переносимо.

Редактировать: Первоначальная проблема заключается в том, что функции, которые ищет предоставленная пользователем библиотека,не в глобальном масштабе.Чтобы это исправить, просто используйте "dl.open" в python, чтобы открыть .so файл главной библиотеки, используя dl.RTLD_NOW и dl.RTLD_GLOBAL.

Success!

1 голос
/ 03 августа 2010

Интерпретатор python, вероятно, загружает вашу оболочку .so, не делая свои символы доступными для других библиотек динамических ссылок (чтобы избежать конфликтов символов).Попробуйте добавить следующие строки непосредственно перед импортом оболочки:

import dl
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)
...