Okay guys... thanks for the help so far.
I was wondering whether to create a new thread or continue on this one... for now I'll just continue here.
I am still trying to create an independent shared library which uses Python underneath but has a plain C API.
I think I have succeeded in that my library works from a C main program and a Go main program but I cannot get it to work from a Python main program through cffi.
This is what I did for my example.
I wrote a core in pure python with core.py
I created the C interfaces to core.py in cython with ccore.pyx
I wrote a shared library libcore.so in C (core.c, core.h) which calls Py_Initialize() and import_ccore().
My example C and Go programs work, but not my Python program.
I put a non-python function in my libcore.so which works from Python via cffi, its the functions which call into Python that don't work.
I put some print statements in the generated ccore_api.h file and found the place it fails is within __Pyx_ImportModule.
Specifically during PyImport_Import(py_name) where the name is ccore.
Its interesting that I was successful in creating a shared library that hides the fact that it uses Python under the hood and it works from C and Go but not from Python.
Any ideas what could be going on here?
=== core.py ===
class Session(object):
def __init__(self, name):
print 'creating session', name
main_session = Session('main')
=== core.pyx ===
import core
cdef api _get_main_session():
return core.main_session
cdef api _new_session(char* name):
return core.Session(name)
cdef api int _is_main_session(s):
return s == core.main_session
=== core.h ===
#ifndef __CORE__H
#define __CORE__H
void* get_main_session();
void* new_session(char* name);
int is_main_session(void*);
int non_python_function(int a, int b);
#endif
=== core.c ===
#include <Python.h>
#include "ccore_api.h"
void init_python_stuff(){
Py_Initialize();
int tmp = import_ccore();
if(tmp){
printf("ERROR IMPORTING CCORE\n");
exit(1);
}
}
void* get_main_session(){
init_python_stuff();
return _get_main_session();
}
void* new_session(char* name){
init_python_stuff();
return _new_session(name);
}
int is_main_session(void* s){
init_python_stuff();
return _is_main_session(s);
}
int non_python_function(int a, int b){
return a + b;
}
=== test.c ===
#include "core.h"
#include <stdio.h>
void* session1 = get_main_session();
void* session2 = new_session("foo");
int answer;
answer = is_main_session(session1);
printf("Session 1 is main? %d\n", answer);
answer = is_main_session(session2);
printf("Session 2 is main? %d\n", answer);
return 0;
}
=== test_go.go ===
package main
import "fmt"
// #cgo LDFLAGS: -L. -lcore
// #include "core.h"
import "C"
func main() {
session1 := C.get_main_session()
session2 := C.new_session(C.CString("BLAH"))
verdict := C.is_main_session(session1);
fmt.Println("Go session1 is main?:", verdict);
verdict = C.is_main_session(session2);
fmt.Println("Go session2 is main?:", verdict);
}
=== test.py ===
#!/usr/bin/env python
from cffi import FFI
ffi = FFI()
ffi.cdef('''\
void* get_main_session();
int non_python_function(int a, int b);
''')
C = ffi.dlopen('libcore.so')
print 'hi 1'
print C.non_python_function(4, 5)
print 'hi 2'
C.get_main_session()
print 'hi 3'