我有一个private.h,public.h而且file.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__ */
Run Code Online (Sandbox Code Playgroud)
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__ */
Run Code Online (Sandbox Code Playgroud)
这是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;
}
Run Code Online (Sandbox Code Playgroud)
我试图做的是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)
Run Code Online (Sandbox Code Playgroud)
它不对 - 它在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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
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
)
Run Code Online (Sandbox Code Playgroud)
import pyximport; pyximport.install()
from person import Person
p = Person('Garry')
print p.name
Run Code Online (Sandbox Code Playgroud)
$ python test_person.py
Garry
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2051 次 |
| 最近记录: |