Я пытаюсь создать интерфейс между c и python. И с помощью интерфейса я хочу вызвать python определяемые пользователем методы из c для некоторых конкретных c операций. Я использую Cython для интерфейса. Учитывая модуль python, я компилирую с использованием Cython и создаю динамическую библиотеку c (.so файл). Затем эта библиотека используется для компиляции программы драйвера c для использования модуля python.
Так что, когда я делаю это из определенной виртуальной среды, где установлен сторонний модуль (используется в модуле ). Работает нормально. Но когда я делаю то же самое вне среды, в которой модуль python не имеет стороннего модуля, он выходит из строя.
Описание кода и процедуры выполняется следующим образом:
pyjlib.pyx (модуль Cython, где определены функции python)
import ujson as json
cdef unicode cstring2unicode(char* s):
if s == NULL:
return None
else:
return s.decode("UTF-8", "replace")
cdef char * unicode2cstring(unicode s):
return s.encode("UTF-8")
cpdef public char * get_ouput(char * cargstr):
cdef unicode argstr = cstring2unicode(cargstr)
cdef dict argdict = json.loads(argstr)
argdict["output"]="cool"
outstr = json.dumps(argdict)
cdef unicode retstr = outstr.decode('UTF-8')
return unicode2cstring(retstr)
В этом модуле я использую ujson
, который является сторонним модулем для распространения python.
compile.py (скрипт для генерации .so файла)
from distutils.core import setup, Extension
module = Extension('pyjlib', ['pyjlib.c'])
setup(
name='pyjlib',
version='1.0',
ext_modules=[module]
)
pyjlib_test. c (c программа драйвера где * Используется модуль 1064 *;)
#include "Python.h"
#include "pyjlib.h"
#include <stdio.h>
int main(int argc, char const *argv[]) {
char * instr = "{\"name\":\"Jai\"}";
Py_Initialize();
initpyjlib();
char * outstr = get_ouput(instr, 0);
Py_Finalize();
printf("input : %s\n\n",instr );
printf("output : %s\n",outstr );
return 0;
}
Для создания динамической библиотеки c соблюдается следующая процедура. Ниже процедура, которую я использовал в виртуальной среде python, где установлен ujson
.
# using cython generate pyjlib.c and pyjloib.h from pyjlib.pyx
cython pyjlib.pyx
# compile .c file to generate .so file
python compile.py build_ext --inplace
# make .so file c compiler/linker recognisable
ln -s pyjlib.so libpyjlib.so
после выполнения вышеописанной процедуры у меня будет файл pyjlib.so
и libpyjlib.so
.
# c driver program compilation
gcc -fPIC -o pyjlib_test pyjlib_test.c -I ./ -I /usr/include/python2.7 `python-config --libs` -L ./ -lpyjlib -lpython2.7
После этого у меня будет исполняемый файл 'pyjlib_test
'
Если я запускаю исполняемый файл внутри того же python virtualenv, то получаю вывод CLI следующим образом:
./pyjlib_test
input : {"name":"Jai"}
output : {"output":"cool","name":"Jai"}
Но если я запускаю его вне virtualenv, вывод CLI будет выглядеть следующим образом:
./pyjlib_test
NameError: name 'json' is not defined
Exception NameError: "name 'json' is not defined" in 'pyjlib.get_ouput' ignored
input : {"name":"Jai"}
output : (null)
Это означает, что я думаю, что во время компиляции python модули третьей стороны включаются или определяются в файле .so.
* Итак, кто-нибудь может помочь, как включить / связать python сторонний модуль в файл .so, чтобы он был доступен из внешней среды python. *
Спасибо.