2017-09-19 1 views
0

Comment compiler en utilisant Cython, une fonction C du fichier simulate_fast.c, où cela dépend également d'autres fichiers C matrix.c et random_generator.c. Cela semble être une utilisation courante de Cython, mais après avoir lu la documentation, je n'arrive toujours pas à comprendre comment le faire. Mon répertoire contient les fichiers suivantsCompilation de plusieurs fichiers C avec Cython

matrix.c 
matrix.h 
random_generator.c 
random_generator.h 
simulate_fast.c 
simulate_fast.h 
test.c 
simulate_fast_c.pyx 
setup.py 

Les matrix.c et random_generator.c fichiers contiennent des fonctions autonomes. Le fichier simulate_fast.c utilise les deux et contient la fonction que je veux exposer à Python, simulate(). Les tests de fichiers test.c que toutes les fonctionnalités de C exécute correctement à savoir que je peux exécuter

$ gcc test.c simulate_fast.c matrix.c random_generator.c -o test 

pour compiler dans un exécutable qui fonctionne test.

Mon problème consiste maintenant à compiler ceci avec Cython. Mon fichier .pyx est

cimport cython 

cdef extern from "simulate_fast.h": 
    int simulate() 

def simulate_cp(): 
    return simulate() 

J'utilise alors le setup.py

from distutils.core import setup 
from Cython.Build import cythonize 
from Cython.Distutils import build_ext 
import numpy as np 

setup(
    name='simulate_fast', 
    ext_modules = cythonize(["simulate_fast_c.pyx"]), 
    include_dirs=[] 
) 

de base Toutefois, si je tente de compiler cela en utilisant

python3 setup.py build_ext --inplace 

Je reçois une erreur

In file included from simulate_fast_c.c:492:0: 
simulate_fast.h:89:28: error: field ‘RG’ has incomplete type 
    struct RandomGenerator RG; 

où la structure RandomGenerator est déclarée dans random_generator.h.

Comment dire au compilateur que nous devons également considérer les fichiers matrix et random_generator lors de la compilation.

Mise à jour

Si vous le faites comme ead dit dans les commentaires, je random_generator.h et inclus dans matrix.hsimulate_fast.h alors le programme est compilée. Cependant, lorsque je tente d'importer le module simulate_fast_c en Python, je reçois un ImportError:

undefined symbol: simulate 

De plus, si je change la ligne de déclaration extern dans simulate_fast.pyx à

cdef extern from "simulate_fast.c": 
    int simulate() 

J'obtiens alors une erreur d'importation

undefined symbol: get_random_number 

qui est une fonction en random_generator.h

+0

Il semble que simulate_fast.h n'est pas autonome, notamment dans random_generator.h simulate_fast.h – ead

+0

C'est vrai même si je reçois encore une erreur pour que je puisse mettre à jour la question. Par curiosité, pourquoi devrais-je inclure le 'random_generator.h' dans l'en-tête' simualte_fast.h' lorsque j'utilise Cython mais pas avec gcc? – rwolst

+0

D'une façon ou d'une autre, simulate_fast.c inclut random_generator.h - cela ne tient pas à ce qu'il provienne de simulate_fast.h ou d'autre part ... – ead

Répondre

1

Le module cythonisé doit être lié à une bibliothèque partagée contenant le code C compilé ou l'incorporer.Une façon de faire ce dernier est de lister les sources C comme étant une « extension », puis passez cette extension à la commande cythonize, comme mentionné dans Cython's documentation

L'exemple de fichier setup.py dans le lien peut être résumée par (modulo la importations):

setup(
    ext_modules = cythonize(Extension("simulate_fast", ["matrix.c", "random_generator.c", "simulate_fast_c.pyx"])) 
)