PY 的 C 扩展疑问

2017-02-25 17:32:42 +08:00
 explist

有如下一个用 C 写的扩展模块: mytest. 我的问题是:在 PY 中如何给实参呢?

#include <stdio.h>

#include "Python.h"

char* gets_s(char s[],int n) {

int c;
char *cs;
if((cs=s)==NULL) return NULL;    
while(--n>0 && (c=getc(stdin))!=EOF && c!='\n')
    *cs++=c;
*cs='\0';
return (c==EOF && cs==s) ||(c=='\n' && cs==s)? NULL : s ;

}

static PyObject* mytest_get(PyObject *self, PyObject *args) {

int n;
char * s=NULL;
if(!PyArg_ParseTuple(args, "si", &s, &n))
        return NULL;
return (PyObject*)Py_BuildValue("s", gets_s(s,n));

}

#python 中:

import mytest

from ctypes import *

arr = (c_byte * 10)() # c_char*10

print('input: ')

mytest.gets_s(arr,10)# TypeError: must be str, not c_byte_Array_10

//另外在C中如何写这样的导出函数:

struct demo {

    char name[10];
    int age;
};

void GetString(struct demo *p) {

    strcpy(p->name, "My Test");
    p->age = 1;
}

static PyObject* wrap_GetString(PyObject *self, PyObject *args) {

struct demo* s;

if(!PyArg_ParseTuple(args, "?", &s)) //这里的类型如何写?

2129 次点击
所在节点    Python
3 条回复
wangxn
2017-02-26 01:37:22 +08:00
这么复杂的东西怎么能三言两语说清楚,楼主去啃啃文档中扩展开发相关的内容吧。
MetaGen
2017-02-26 20:23:41 +08:00
用 cffi 多简单,为啥要用 CPython 的接口
Daetalus
2017-03-01 18:11:46 +08:00
第一个问题,从原理上来说, Python 中字符串是不可变的。而根据 C 模块的代码,"si"表示接收的是字符串,而 Python 中字符串是不可变的,因此不能像 C 语言中那样先创建一个长度为 10 的空字符串,然后传入函数,在函数中修改其中的内容(这只是原理,你的代码中并没有修改)。因此要么用字符列表,要么就改变思维方式。

又看了下你的代码,我觉得可以直接使用 input()函数,获取字符串对象,然后传到 C 层面中并解析给一个 const char*对象。如果仅仅想实验一些 C API 的功能,还是要注意 Python 和 C 在思维上的差别。

PS :你的 C 代码写的不错啊!看上去是有经验的。


第二个问题, Python 中所有都是对象,这个对象在 C 层面指的是 PyObject ,所以从 Python 层面传来的参数不能直接通过`if(!PyArg_ParseTuple(args, "?", &s))`解析给 C 层面的纯 struct 对象。

有几种解决方案:

1 、弄个中间的结构体,其中含有 PyObject_HEAD :

typedef struct {
PyObject_HEAD
xxx;
} PyXxxxObject;

然后将这个对象转成 demo 对象。要么直接把 demo 定义成 PyObject 对象。之后就是传递 O 对象了。

2 、使用 struct 模块,位于标准库中,不用担心移植性。具体参考相关文档。

3 、利用 PyDictObject 和 PyListObject 进行一些较为复杂的模拟。应该是可行的,但我没想好细节。就不给出代码了。

对了,强烈、强烈建议不要混用 ctype 和 Python C API 。

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

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

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

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

© 2021 V2EX