I am trying to make an interface between c and python. And by suing interface i want to call python user defined methods from c for some specific operations. I am using Cython for interface. Given a python module, i am compiling using cython and generating dynamic library (.so file). Then that library is being used to compile c driver program to make use of python module.
So when i am doing this from particular virtual environment where the third-party module is installed (used in module). Its working fine. But when i do the same thing outside the environment where python module doesn't have third-party module its failing.
Description of code and procedure does as follows;
pyjlib.pyx (cython module where python functions are defined)
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)
In the this module i am using ujson
, which is a third party module to python distribution.
compile.py (script to generate .so file)
from distutils.core import setup, Extension
module = Extension('pyjlib', ['pyjlib.c'])
setup(
name='pyjlib',
version='1.0',
ext_modules=[module]
)
pyjlib_test.c (c driver program where python module is being used;)
#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;
}
To generate dynamic library below procedure is being followed. Below procedure i used to in a python virtual environment where ujson
is installed.
# 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
after doing above procedure, i will have pyjlib.so
and libpyjlib.so
file.
# 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
After doing this i will have executable 'pyjlib_test
'
If i run the executable inside same python virtualenv then i get CLI output as follows;
./pyjlib_test
input : {"name":"Jai"}
output : {"output":"cool","name":"Jai"}
But if I run it outside the virtualenv, CLI output goes as follows;
./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)
Which means i think, during the compilation python thrird party modules are included or defined in .so file.
*So can anyone please help how to include / bundle python third-party module to .so file so that it can be accessible from outside python environment. *
Thank you.