我有一个相对复杂的 C 程序想用 Cython 将其中的某几个函数封装了给 Python 调用,由于太复杂想写个结构类似但简单的小程序试着用 Cython 封装,代码area.c
如下:
#include <stdio.h>
#include <string.h>
struct Square {
float length;
float width;
};
typedef struct Square *sq;
float calc_area(sq a) {
float s;
s = a->length * a->width;
return s;
}
int main() {
sq a;
a->length = 10.0;
a->width = 3.0;
printf("%f\n", calc_area(a));
}
问题一:
gcc area.c -o area.exe
能够编译成功,但运行时在 mac 上提示 bus error ,在 linux 上提示段错误。有朋友告诉我把sq a;
改成sq a=new Square();
然后用 g++编译,确实能够成功,但这样就和原来复杂的程序产生了结构性变化。原复杂程序里面的定义和我这个简单程序是一样的,但能够成功运行,不知道为什么这个简单程序就出错了。
问题二:
如果这个简单的程序能够运行,如何将calc_area()
这个函数用 Cython 封装呢?主要的难点是,这里 sq 是个结构体指针, Cython 貌似并没有能力自动处理这种非常规类型的接口。
求各位 V 友指点!谢谢
1
herozem 2017-01-12 13:09:45 +08:00 1
因为,你的 c ,写错了。
#include <stdio.h> #include <string.h> struct Square { float length; float width; }; typedef struct Square *sq; float calc_area(const sq a) { float s; s = a->length * a->width; return s; } int main() { struct Square a; a.length = 10.0; a.width = 3.0; printf("%f\n", calc_area(&a)); } |
2
lyricorpse OP @herozem 多谢回复 但是我定义和赋值的写法都是按照那个复杂 C 程序写的。
比如用 typedef 把 sq 指针定义成 Square 结构体后,后面就一直用 sq 了,定义时没有再 struct Square a 而是直接 sq a ;函数的参数也没有 const sq a 而是 sq a 。 但是那个复杂程序用 gcc 编译成功,运行时也没出问题。 我上面提到,如果把 sq a;改成 sq a=new Square(); 用 g++就能编译成功可运行,请问这个地方怎么解释呢? |
3
Andiry 2017-01-12 13:27:21 +08:00 1
sq a;
只是声明了一个指针。指针指向的空间没有分配。 |
4
lyricorpse OP @Andiry 啊。。确实漏掉了,原复杂程序中有一段 malloc 藏在 if 里没注意。。感谢!
|
5
MCVector 2017-01-12 13:54:46 +08:00 via Android 1
指针没有释放,有内存泄漏。最后还要 free(a); 而且这段程序其实没有必要用指针吧。
|
6
lyricorpse OP @MCVector 多谢提醒,这个小程序是一个很复杂的大程序的简化,我主要是想搞明白如何封装了给 Python 调用。我第一次尝试封装 C 程序,所以先写个简单的试试。
|
7
MCVector 2017-01-12 14:10:56 +08:00 via Android 1
@lyricorpse 可以试试 boost Python 封装成 module 。 或者直接用 libpython 也行。之前写过一个[简单例子]( https://github.com/v3c70r/GL4Framework/blob/dev/src/app/pyConsole.cpp), 看看能不能帮到你。
|
8
lyricorpse OP @MCVector 谢谢!我试试看
|