我想从Python调用一个C函数,它应该创建并初始化一个struct。我希望这个结构转换为Python对象作为Python中的返回值。
答案 0 :(得分:0)
以下是实现我想要的示例文件(基于Accessing C struct array to Python with SWIG),即create_struct()
创建并初始化可以在Python中使用的结构。感谢John Bollinger帮助修复错误。
#include <stdint.h>
struct Foo
{
uint8_t a[4];
};
void create_struct(struct Foo** new_struct);
#include <string.h>
#include "example.h"
void create_struct(struct Foo** new_struct){
struct Foo* foo = (struct Foo*) malloc(sizeof(struct Foo));
uint8_t tmp[4] = {0,1,2,3};
memcpy(foo->a, tmp, 4);
*new_struct = foo;
}
%module example
%{
#define SWIG_FILE_WITH_INIT
#include "example.h"
%}
// Define input and output typemaps for a
%typemap(in) uint8_t a[4] {
if (!PyBytes_Check($input)) {
PyErr_SetString(PyExc_TypeError, "Expecting a bytes parameter");
SWIG_fail;
}
if (PyObject_Length($input) != 4) {
PyErr_SetString(PyExc_ValueError, "Expecting a bytes parameter with 4 elements");
SWIG_fail;
}
uint8_t res[4];
char* bytes = PyBytes_AsString($input);
int i;
for (i=0; i<4; i++) {
res[i] = (uint8_t) bytes[i];
}
$1 = res;
}
%typemap(out) uint8_t a[4] {
$result = PyBytes_FromStringAndSize((char*) $1, 4);
}
/*
* This fails with "Warning 453: Can't apply (struct Foo *OUTPUT). No typemaps are defined.":
* %apply struct Foo* OUTPUT {struct Foo* new_struct };
* So I'm trying to define typemaps for struct Foo*
*/
// This typemap suppresses requiring the parameter as an input.
%typemap(in,numinputs=0) struct Foo** new_struct (struct Foo* temp) {
$1 = &temp;
}
%typemap(argout) struct Foo** new_struct {
$result = SWIG_NewPointerObj(*$1, $descriptor(struct Foo*), SWIG_POINTER_OWN);
}
%include "example.h"
extern void create_struct(struct Foo** new_struct);
#!/usr/bin/env python3
from distutils.core import setup, Extension
module1 = Extension('example', sources=['example.c', 'example.i'])
setup(name='Example', version='0.1', ext_modules=[module1])
#!/usr/bin/env python3
import example
foo = example.create_struct()
print("foo.a: %r" % foo.a)
python3 setup.py build_ext --inplace && mv example.*.so _example.so && python3 test.py
测试代码应打印foo.a: b'\x00\x01\x02\x03'
。