Встроить функцию Python в переполнение стека

Я экспериментирую с Cython, чтобы сгенерировать код c из python, но, похоже, есть некоторые проблемы с искажением имен. Сначала я генерирую конвертируем код из python в c, а затем компилирую код, используя gcc, в .so. Причина, по которой я хочу использовать Cython вместо C / python API, заключается в том, что позже я буду использовать это в более сложных классах, которые я хотел бы использовать в качестве библиотеки для скорости и т. Д. (У меня много проблем с поиском людей, которые с питона на C ++, так как обычно все наоборот). Ниже приведен весь код, который я должен попытаться выполнить код (но не удается). Любой вклад будет оценен. Спасибо!

#hello.pyx
def say_hello():
print "Hello World!"
#generate the c code
cython -a hello.pyx

#creates the shared library
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.6 -o libhello.so hello.c

//temp.cpp
#include <iostream>
extern "C" {
void say_hello();
};

using namespace std;

int main(){
say_hello();
return 1;
};

#attempt to compile (this is where it fails)
g++ -I/usr/include/python2.6/ -lpython2.6 -L./ -lhello temp.cpp -o temp

Вот сообщение об ошибке:

/tmp/ccpKHOMl.o: In function main: temp.cpp:(.text+0x5): undefined reference to say_hello' /tmp/ccpKHOMl.o:
In function __static_initialization_and_destruction_0(int, int):
temp.cpp:(.text+0x33): undefined reference to std::ios_base::Init::Init()
temp.cpp:(.text+0x38): undefined reference to std::ios_base::Init::~Init()
collect2: ld returned 1 exit status

4

Решение

Вы не сможете получить взаимодействие, которое вы хотите таким образом. Если вы откроете и осмотрите hello.c, вы не найдете «static int say_hello» там. Cython предназначен для того, чтобы позволить Python использовать библиотеки C, а не для библиотек C использовать Python.

Вы можете посмотреть здесь в документации, но, к сожалению, эта поддержка все еще для интерпретатора Python, который «отвечает», а то, что вы ищете, — наоборот.

http://docs.python.org/release/2.5.4/ext/callingPython.html

Также есть учебник по «Встраиванию Python в другое приложение».

http://docs.python.org/2/extending/embedding.html

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

3

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

Я столкнулся с подобной проблемой. Это не совсем та же проблема, но это может быть связано.

Я разместил свой вопрос здесь: Распространение исключений через dlsym cython. Интересующая вас часть — это ключевое слово public:

#hello.pyx
cdef public say_hello():
print "Hello World!"

Это создаст такую ​​функцию

# (in the generated C file hello.c)
__PYX_EXTERN_C DL_IMPORT(...) say_hello(...);

Редактировать: я добавил рабочий temp.cpp:

#include "Python.h"#include <iostream>

#include "hello.h"
using namespace std;

int main(){
Py_Initialize();
inithello();
say_hello();
Py_Finalize();
return 1;
};

Компиляция выполняется с помощью:

g++ -I/usr/include/python2.6/ -lpython2.6 -L./ -lhello temp.cpp -c -o temp.o
g++ temp.o -L. -lhello -lpython2.6 -o temp

(Интересно, что он не будет ссылаться на один шаг, жалуясь на неопределенные ссылки.)
Это успешно напечатает «Hello world» после выполнения.

Примечание: Py_Initialize () и inithello () необходимы, иначе ваш код вылетит. Я не смог заставить его работать без включения «Python.h» и без частей инициализации (т. Е. Используя только extern «C» {void sayhello ();}, как вы упомянули). Это не в соединении. Решением может быть использование dlsym и динамическая загрузка вашей функции, как я продемонстрировал в своем вопросе. Но, вероятно, существует другое решение, в котором вы пытаетесь успешно экспортировать этот метод (в заголовке hello.h):
__PYX_EXTERN_C DL_IMPORT (int) say_hello (void);

1

Если у вас есть CMake, я предлагаю взглянуть на мой проект, где я использую CMake для генерации и связывания файлов на основе Cython.

https://github.com/CarloNicolini/cymake

Вы, вероятно, должны отредактировать какой-нибудь CMakeLists.txt, чтобы найти правильную установку Cython

0
По вопросам рекламы [email protected]