имена общих библиотечных символов

Я хотел бы иметь возможность использовать функции C / C ++ из Python с использованием модуля Python ctypes.

У меня есть функция int doit() в .c / .cpp файл. Когда я пытаюсь загрузить общую библиотеку:

Frr=CDLL("/path/FoCpy2/libFrr.so")
Frr.doit(c_int(5))

я считаю, что это работает очень хорошо, когда .c вариант используется. Когда вызывается C ++, хорошим способом вызова этой функции является (выясняется с помощью nm libFrr.so с помощью nm -gC libFrr.so производит просто doit()):

Frr._Z4doitv(c_int(5))

Я прочитал на Stackexchange, что нет стандартного способа вызова C ++ из python, и есть проблема «нестандартного искажения имени». Является ли «Z4» частью этой проблемы? Я предполагаю, что нестандартное искажение имени появилось бы для более продвинутых функций языка, таких как методы класса, шаблоны, но также и для таких основных функций? Можно ли принудительно использовать простые имена функций C в простых случаях для кода C ++?

2

Решение

Ты можешь использовать extern "C" сделать так, чтобы функции выглядели как функции C для внешнего мира (то есть отключить искажение имен). И да, вы правы, преобразование имен необходимо в основном для более сложных функций и типов функций, которые есть в C ++, а схема преобразования имен никогда не была стандартизирована (и двоичная совместимость), поэтому она варьируется от компилятора к компилятору. и между версиями (но большинство компиляторов основного потока в настоящее время установили что-то постоянное, но между поставщиками компиляторов все еще различаются). И причина того, что искажение также требуется для простых старых свободных функций, заключается в том, что C ++ поддерживает перегрузку (те же имена функций, но с разными параметрами), и, таким образом, компиляторы будут кодировать спецификацию параметров (например, типы) в искаженные имена. Конечно, если вы используете extern "C" вы теряете все функции, для которых необходимо преобразование имен, поэтому оно более или менее сводится только к функциям C.

Ты можешь использовать extern "C" либо для каждой функции, например, так:

extern "C" int doit();

Или для общего заголовка:

extern "C" {

// all the function declarations here ...

};

Однако, особенно для Python, я настоятельно рекомендую вам использовать библиотеку, которая позволяет вам создавать классы и функции Python, которые отражают ваши классы и функции C ++, что делает жизнь намного проще и скрывает весь этот внешний бизнес «C» , Я рекомендую использовать Boost.Python, видеть это Начальная страница, это делает экспорт функций и классов в Python быстрым. Я думаю, что другие также рекомендуют SWIG, но я никогда не использовал это.

2

Другие решения

Вызов библиотечных функций c ++ всегда беспорядок, даже если вы используете C ++, вы должны использовать тот же компилятор и т. Д., Чтобы убедиться, что он работает.

Единственное общее решение — определить ваши функции c ++ как extern "C" и убедитесь, что вы соблюдаете соответствующие ограничения — см. Вот для объяснения этого.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector