Use of cython pure python mode in C

2019-08-21 10:00发布

问题:

As far as I understood the pure python mode, it seems possible to use a script python with augmenting pxd in order to use the python function directly in a C program.

I am looking for a way to do so since I am stuck on the program compilation with the following errors:

gcc -L/usr/local/python-gnu-2.7.8/lib -lpython2.7 -I/usr/local/python-gnu-2.7.8/include/python2.7 -I. -L. -lfoo -o main main.o
main.o: In function `main':
/d/sverley/Etudes/SIMELING/LivBinh052018/static_model/test_cython/main.c:11: undefined reference to `_helper'
/d/sverley/Etudes/SIMELING/LivBinh052018/static_model/test_cython/main.c:12: undefined reference to `myfunction'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1

The following example is coming from the cython documentation with simplification/modification.

Files are:

  • foo.py: the python module
  • foo.pxd: the associated header file for cython compiler
  • main.c: the C program in which I need to use the python object

foo.py

from __future__ import print_function

def myfunction(x, y=2):
    a = x - y
    res = a + x * y
    print("myfunction:result is:", res)
    return res

def _helper(a):
    res = a + 1
    print("_helper:result is:", res)
    return res

foo.pxd

cdef public double _helper(double a)
cpdef public int myfunction(int x, int y=*)

main.c

#include <stdio.h>
#include <stdlib.h>
#include <Python.h> //needed
#include <foo.h>

int main(void){
    Py_Initialize();  //Needed!
    initfoo();      //Needed! called PyInit_hello() for Python3
    printf("Result _helper   : %f\n", _helper(3.) );
    printf("Result myfunction: %d\n", myfunction(3,2); );
    Py_Finalize();    //Needed!
}

Makefile

CC     := gcc
# CFLAGS := $(shell python-config --cflags)
CFLAGS := -g -ggdb -O0 -D_DEBUG -Wall #-Werror
LDFLAGS:= -shared
# CLIBS  := -L$(shell python-config --prefix)/lib $(shell python-config --ldflags)
CLIBS  := -L/usr/local/python-gnu-2.7.8/lib -lpython2.7
RM     := rm -f
CYTHON := cython

INCLUDE_PATH := -I/usr/local/python-gnu-2.7.8/include/python2.7

.PHONY: all clean

NAME := main
CYTHONSRC := foo.py
CYTHONOBJS := $(CYTHONSRC:.py=.so)
LIBS := libfoo.so
SRCS := main.c # $(wildcard *.c)
OBJS := $(SRCS:.c=.o)

all: $(NAME)

lib: $(LIBS)

#
libfoo.so: foo.o
    $(CC) -I. -L. $(LDFLAGS) $(CLIBS) -o $@ $^
#
# link the .o files into the target executable
#
$(NAME): $(LIBS) $(OBJS)
    $(CC) $(CLIBS) $(INCLUDE_PATH) -I. -L. -lfoo -o $@ $@.o
#
# compile the .c file into .o files using the compiler flags
#
%.o: %.c
    $(CC) $(CFLAGS) $(INCLUDE_PATH) -I. -c -fPIC $<

%.c: %.py %.pxd
    python -m cython $<

clean:
    $(RM) $(CYTHONSRC:.py=.c)
    $(RM) $(CYTHONSRC:.py=.h)
    $(RM) $(CYTHONSRC:.py=.o)
    $(RM) $(LIBS)
    $(RM) $(OBJS)
    $(RM) $(NAME)
标签: python cython