一个简单的 C 程序 bus error,以及如何用 Cython 进行封装

2017-01-12 12:53:49 +08:00
 lyricorpse

我有一个相对复杂的 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 友指点!谢谢

2056 次点击
所在节点    问与答
8 条回复
herozem
2017-01-12 13:09:45 +08:00
因为,你的 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));
}
lyricorpse
2017-01-12 13:20:27 +08:00
@herozem 多谢回复 但是我定义和赋值的写法都是按照那个复杂 C 程序写的。
比如用 typedef 把 sq 指针定义成 Square 结构体后,后面就一直用 sq 了,定义时没有再 struct Square a 而是直接 sq a ;函数的参数也没有 const sq a 而是 sq a 。
但是那个复杂程序用 gcc 编译成功,运行时也没出问题。

我上面提到,如果把 sq a;改成 sq a=new Square(); 用 g++就能编译成功可运行,请问这个地方怎么解释呢?
Andiry
2017-01-12 13:27:21 +08:00
sq a;
只是声明了一个指针。指针指向的空间没有分配。
lyricorpse
2017-01-12 13:31:40 +08:00
@Andiry 啊。。确实漏掉了,原复杂程序中有一段 malloc 藏在 if 里没注意。。感谢!
MCVector
2017-01-12 13:54:46 +08:00
指针没有释放,有内存泄漏。最后还要 free(a); 而且这段程序其实没有必要用指针吧。
lyricorpse
2017-01-12 14:02:10 +08:00
@MCVector 多谢提醒,这个小程序是一个很复杂的大程序的简化,我主要是想搞明白如何封装了给 Python 调用。我第一次尝试封装 C 程序,所以先写个简单的试试。
MCVector
2017-01-12 14:10:56 +08:00
@lyricorpse 可以试试 boost Python 封装成 module 。 或者直接用 libpython 也行。之前写过一个[简单例子]( https://github.com/v3c70r/GL4Framework/blob/dev/src/app/pyConsole.cpp), 看看能不能帮到你。
lyricorpse
2017-01-12 14:22:51 +08:00
@MCVector 谢谢!我试试看

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/334094

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX