python - 包装 C 库

标签 python c cython

<分区>

我有一个private.hpublic.hfile.c,我需要把它包装成Cython . 如何包装函数 Person_ptr Person_create(const char* name);

private.h:

#ifndef __PERSON_PRIVATE_H__
#define __PERSON_PRIVATE_H__

#include "Person.h"

typedef struct Person_TAG {
    char* name;
    int age;
} Person;


void person_init(Person_ptr self, const char* name);

# endif /* __PERSON_PRIVATE_H__ */

public.h

#ifndef __PERSON_H__
#define __PERSON_H__

#include <assert.h>

typedef struct Person_TAG* Person_ptr;

#define PERSON(x) \
    ((Person_ptr) (x))

#define PERSON_CHECK_INSTANCE(x) \
    assert(PERSON(x) != PERSON(NULL))

/* public interface */
Person_ptr Person_create(const char* name);
void Person_destroy(Person_ptr self);

const char* Person_get_name(const Person_ptr self);
int Person_get_age(const Person_ptr self);
void Person_birthday(Person_ptr self);

# endif /* __PERSON_H__ */

这是file.c:

#include "Person.h"
#include "Person_private.h"

#include <stdlib.h>
#include <string.h>
#include <assert.h>

Person_ptr Person_create(const char* name)
{
    Person_ptr self = PERSON(malloc(sizeof(Person)));
    PERSON_CHECK_INSTANCE(self);
    person_init(self, name);
    return self;
}

void Person_destroy(Person_ptr self)
{
    PERSON_CHECK_INSTANCE(self);
    if (NULL != self->name) free(self->name);
}

 /* Do not free not change the returned string! */
const char* Person_get_name(const Person_ptr self)
{
    PERSON_CHECK_INSTANCE(self);
    return self->name;
}

int Person_get_age(const Person_ptr self)
{
    PERSON_CHECK_INSTANCE(self);
    return self->age;
}

void Person_birthday(Person_ptr self)
{
    PERSON_CHECK_INSTANCE(self);
    ++self->age;
}

/* private/protected methods */
void person_init(Person_ptr self, const char* name)
{
    self->name = malloc(sizeof(char) * (strlen(name) + 1));
    assert(NULL != self->name);
    strcpy(self->name, name);
    self->age = 0;
}

我尝试做的是 file.pyx:

from ctypes import *

cdef extern from "Person.h":
ctypedef struct Person_ptr:
        pass
Person_ptr Person_create "P_create" (char *name)

cdef class Person:
    cdef Person P_create(p_name):
    return Person_create(p_name)

这是不对的——它在 Cython 中编译,但在 GCC 中给我带来了很多错误。 我该如何解决这个问题?

最佳答案

cperson.pxd:

cdef extern from "Person.h":
    cdef struct Person_TAG:
        pass
    ctypedef Person_TAG* Person_ptr

    Person_ptr Person_create(char* name)
    void Person_destroy(Person_ptr self)

    char* Person_get_name(Person_ptr self)

person.pyx :

from cperson cimport Person_ptr, Person_create, Person_destroy, Person_get_name

cdef class Person:
    cdef Person_ptr thisptr

    def __cinit__(self, char* name):
        self.thisptr = Person_create(name)
        if self.thisptr is NULL:
            raise MemoryError

    def __dealloc__(self):
        if self.thisptr is not NULL:
            Person_destroy(self.thisptr)

    property name:
        def __get__(self):
            return Person_get_name(self.thisptr)

人.pyxbld:

import os
from distutils.extension import Extension

dirname = os.path.dirname(__file__)

def make_ext(modname, pyxfilename):
    return Extension(name=modname,
        sources=[pyxfilename, "Person.c"],
        include_dirs=[dirname],
        # or libraries=["person"], if you compile Person.c separately 
        )

test_person.py :

import pyximport; pyximport.install()

from person import Person

p = Person('Garry')
print p.name

例子

$ python test_person.py 
Garry

关于python - 包装 C 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7619785/

相关文章:

c# - 捕获发往某个IP和端口的网络数据包并将其存储在队列中

Android NDK C#ifndef 问题

python - 在解释器中运行 Cython 代码

python - Noob-Ready Cython 教程

python - 如何打印十六进制值?

python - 选择 Dataframe 的一部分以获得 View ,而不是副本

c - strtok 中的段错误(核心已转储)

python - python中的类似乎不是全局的

python 时间偏移

python - 在 C++ 中嵌入 Cython 类方法