在cython中使用typedef'd结构

时间:2014-08-28 08:49:53

标签: python c typedef cython

我在头文件dcm.h中有以下定义:

typedef struct
{    
    double alpha;
    double gamma;
    double tau;
} ThetaDCM;

我想在cython中导入它,所以我有:

cdef extern from "dcm.h":

    ctypedef struct ThetaDCM:

        np.float64_t alpha
        np.float64_t gamma
        np.float64_t tau

现在我想将内存分配给ThetaDCM的数组。我有以下内容:

cdef ThetaDCM *c_theta = <ThetaDCM *> malloc(nt * nb * sizeof(ThetaDCM))

free(c_theta)

这没有编译并报告了以下错误:

error: ‘ThetaDCM’ undeclared (first use in this function)
   __pyx_v_c_theta = ((ThetaDCM *)malloc(((__pyx_v_nt * __pyx_v_nb) * (sizeof(ThetaDCM)))));

还有其他与此相关的错误。如果我在extern块之外定义ThetaDCM,代码编译没有问题。因此,如果我导入Theta,cython无法看到我的声明。有没有标准的解决方法?

修改

我的文件标题比我发布的文件要复杂一些。这是

# ifdef __CUDACC__
# ifndef DDM_HEADER
# define DDM_HEADER

#include "math.h"
#include "curand_kernel.h"
#include "curand.h"
#include <stdio.h>
...
# endif 

# ifdef __CUDACC__
# define BDDM_EXTERN extern "C"
# else
# define BDDM_DEVICE
# endif

BDDM_EXTERN
int llh_m0t( double *x, double *y, double *u,
    double *theta, double *ptheta, int ny, int nt, double *llh);
...
typedef struct
{    
    double alpha;
    double gamma;
    double tau;
} ThetaDCM;

# endif 

top上的指令用于检查编译器是否为nvcc,是cuda代码的编译器。现在我意识到有一个错误,我应该有:

# ifndef DDM_HEADER
# define DDM_HEADER
# ifdef __CUDACC__

#include "math.h"
#include "curand_kernel.h"
#include "curand.h"
#include <stdio.h>
...
# endif

BDDM_EXTERN
int llh_m0t( double *x, double *y, double *u,
    double *theta, double *ptheta, int ny, int nt, double *llh);
...

typedef struct
{    
    double alpha;
    double gamma;
    double tau;
} ThetaDCM;
# endif 

令我感到困惑的是,尽管#ifdef CUDACC ,编译的 cython 代码仍然存在。我使用cython来包装在第一个#ifdef语句中定义的c函数(比如llh_m0t),所以令人困惑的是cython可以看到那些函数定义。

2 个答案:

答案 0 :(得分:1)

可能是 cython 的旧版(或 beta ?)版本的问题。

我同意这不是一个真正的答案 - 主要是一个非常长的评论...但这对我来说使用 cython 0.20.0

  

<子> dcm.h

typedef struct
{    
    double alpha;
    double gamma;
    double tau;
} ThetaDCM;


  

<子> dcm.pyx

cimport numpy as np
from libc.stdlib cimport malloc, free

nt = 1
nb = 1

cdef extern from "dcm.h":

    ctypedef struct ThetaDCM:

        np.float64_t alpha
        np.float64_t gamma
        np.float64_t tau

cdef ThetaDCM *c_theta = <ThetaDCM *> malloc(nt * nb * sizeof(ThetaDCM))

print(hex(<long>c_theta))

free(c_theta)
sh$ cython dcm.pyx
sh$ gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I../include/python3.4m/ -L../lib/python3.4/ dcm.c -o dcm.so
sh$ python3Python 3.4.1 (default, Aug 20 2014, 14:47:11) 
[GCC 4.7.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import dcm
0x23e44f0

答案 1 :(得分:1)

Cython不会根据标题的要求为#define宏提供条件编译支持:

  

<子> dcm.h

# ifdef __CUDACC__

typedef struct
{    
    double alpha;
    double gamma;
    double tau;
} ThetaDCM;

# endif

快速解决方法:

  

<子> dcm.pyh

#define __CUDACC__
#include "dcm.h"


  

<子> dcm.pyx

[...]

cdef extern from "dcm.pyh":
#                     ^^^
    [...]