包装C库 [英] Wrapping C library
本文介绍了包装C库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个 private.h
, public.h
和 file.c
,我需要将其包装到 Cython 中。
如何包装函数 Person_ptr Person_create(const char * name);
?
I have a private.h
, public.h
and the file.c
, and I need to wrap it into Cython.
How do I wrap the function 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:
What I have tried to do is 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错误。
如何解决此问题?
It's not right - it compiles in Cython but then it gives me a lot of errors in GCC. How can I fix this problem?
推荐答案
cperson.pxd:
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)
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)
person.pyxbld:
person.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
)
import pyximport; pyximport.install()
from person import Person
p = Person('Garry')
print p.name
示例
Example
$ python test_person.py
Garry
这篇关于包装C库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文