Cython:无法将Python对象转换为struct

时间:2014-09-22 09:38:01

标签: python cython

警告:我是Cython的新手。 :d 我有以下几段代码:

my_structs.h:

typedef struct Dataset{
    int lines;
    char **tid;
}Dataset;

myiolib.pyx:

from libc.stdlib cimport malloc
from libc.string cimport strcpy
from cpython.string cimport PyString_AsString

cdef extern from "my_structs.h":
    cdef struct Dataset:
        int lines
        char **tid


cdef Dataset readDataset(TID_name):
    cdef:
        int i, line_count=0
        Dataset instance

    with open(TID_name, 'rU') as file_iter:
        for line in file_iter:
            line_count=line_count+1

    instance.tid = <char **>malloc(line_count * sizeof(char *))

    i = 0
    with open(TID_name, 'rU') as file_iter:
        for line in file_iter:
            instance.tid[i] = <char *>malloc((len(line)+1) * sizeof(char ))
            strcpy(instance.tid[i], PyString_AsString(line.strip()))
            i += 1

    instance.lines = line_count
    return instance

mytest.pyx:

import myiolib

cdef extern from "my_structs.h":
    cdef struct Dataset:
        int lines
        char **tid


def test():
    cdef Dataset D
    D = myiolib.readDataset("test.dat")

    # Do something...
    # Free memory (?!)

test.py:

import mytest

mytest.test()

当我键入:cython -a mytest.pyx时,它说:&#34;无法将Python对象转换为&#39;数据集&#39; &#34 ;, 指着D = myiolib.readDataset(&#34; test.dat&#34;)。 为什么?我不明白......我做错了什么?

1 个答案:

答案 0 :(得分:1)

首先,我认为你的最小例子非常糟糕。您不包含setup.py或任何其他运行代码的方式。

因此,这是一个恰当的最小例子:

test_python.py

import pyximport
pyximport.install(setup_args={'include_dirs': "."})

import my_test

my_test.test()

my_test.pyx

import my_library

cdef extern from "my_type.h":
    cdef struct MyType:
        int x

def test():
    cdef MyType my_instance
    my_object = my_library.my_function()

my_library.pyx

cdef extern from "my_type.h":
    cdef struct MyType:
        int x

cdef MyType my_function():
    return MyType()

my_type.h

typedef struct MyType {
    int my_attribute;
} MyType;

此错误:

AttributeError: 'module' object has no attribute 'my_function'

这是因为正在使用cdef,因此import将不允许访问该功能。你也使用过cdef,所以我很惊讶这不会发生在你身上。也许用setup.py编译不需要这个;这不会让我感到惊讶。尽管如此,您仍然在使用import cimport

添加my_library.pxd

cdef extern from "my_type.h":
    cdef struct MyType:
        int x

cdef MyType my_function()

可选择从cdef extern文件中删除pyx并更改

import my_library

cimport my_library

它有效。

如果这些提示无法解决,请举个例子我可以运行。