急!!!Python中扩展C遇到的结构体参数传递问题

fengmang_0451 2009-07-26 12:08:51
最近刚开始学Python,现要在Python中扩展C,在测试Python脚本test.py中调用一个C函数,输入参数为整型和字符串,输出参数为结构体指针。但是怎么结构体指针不能返回改变的值呢?
我把源代码贴出来,各位大侠帮忙分析一下
----------- 1.C程序头文件(information.h)-----------

typedef struct {
char name[20];
int height;
int weight;
} Infor;

int getInfor( char* name, int height, int weight, Infor* infor);

----------- 2.C程序源文件(information.c)-----------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "Extest.h"
int getInfor( char* name, int height, int weight, Infor* infor)
{
if(name == NULL || infor == NULL)
return (-1);

printf(" [%s] get params: name[%s] height[%d] weight[%d]\n", __FUNCTION__, name, height, weight);

strcpy(infor->name, name);
infor->height = height;
infor->weight = weight;
return (1);
}

----------- 3.C程序包装文件(information_wrap.c)-----------
注:没有采用swig等工具自动包装,而是手写包装函数。

#include "Python.h"
#include "ceval.h"
#include "Extest.h"

static PyObject * Extest_getInfor(PyObject *self, PyObject *args)
{
char* name;
int height;
int weight;
Infor* infor;
int res;

if(!PyArg_ParseTuple(args, "siiO:infor", &name, &height, &weight, &infor)){
return NULL;
}

printf(" ***** Before Call: infor.name[%s] infor.height[%d] infor.weight[%d] *****\n",infor->name, infor->height, infor->weight);//【1】初始值
res = getInfor(name, height, weight, infor);
printf(" ***** After Call: infor.name[%s] infor.height[%d] infor.weight[%d] *****\n", infor->name, infor->height, infor->weight);//【2】改变后的值

return (PyObject*)Py_BuildValue("i", res);
}

static PyMethodDef ExtestMethods[] = {
{ "getInfor", Extest_getInfor, METH_VARARGS },
{ NULL, NULL },
};

void initExtest(void)
{
PyObject *m;
m = Py_InitModule("Extest", ExtestMethods);
}

----------- 4.编译Makefile文件(Makefile)-----------
注:这里我直接写的Makefile,当然采用setup.py进行build的方式也一样

# Makefile of Extend C for Python
OBJS = Extest.o ExtestWrappers.o
SOLIBS =
SOLIBDIR =
TARGET = Extest.so
INCLUDES = -I /usr/local/include/python2.6/
MAKEFILE = Makefile
CC = gcc
DEBUG =
CFLAGS = -fPIC -Wall -Wstrict-prototypes -Winline \
${INCLUDES} -O2 $(DEBUG)
all : ${TARGET}
${TARGET} : ${OBJS} ${LIBS}
${CC} -shared -o ${TARGET} ${OBJS} ${SOLIBS} ${SOLIBDIR}
rm -f ${OBJS}
clean :
rm -f *.o *.Z* *~ ${TARGET}

----------- 5.测试用Python文件(test.py)-----------

#!/usr/bin/env python2.6
#coding=utf8
#----- 调用扩展C程序接口的测试程序 -----#
import Extest
from ctypes import *

class Infor(Structure):
_fields_= [('name', c_char*20),
('height', c_int),
('weight', c_int)]

def main():
infor = Infor()
infor.name = 'NoName'
infor.height = -1
infor.weight = -1

name = 'TestName'
height = 175
weight = 160

print 'Before call getInfor(), Infor.name=%s Infor.height=%d Infor.weight=%d' % (infor.name, infor.height, infor.weight)
Extest.getInfor(name, height, weight, byref(infor))
print 'After call getInfor(), Infor.name=%s Infor.height=%d Infor.weight=%d' % (infor.name, infor.height, infor.weight) #【3】测试返回的结构体
print ' ----- all DONE -----'

if __name__ == '__main__':
main()


编译没问题,运行时,在包装文件information_wrap.c中的【1】处打印出的信息name值还是“NoName”,在【2】处是改变后的“TestName”,但是返回到测试Python文件,【3】处的信息中,name值还是“NoName”,为什么改变后的值不能传回来啊?
传递的参数不是结构体变量的指针吗?

各位Python大虾,还请多多指教!!!
...全文
426 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
InOner 2009-09-26
  • 打赏
  • 举报
回复
仔细看看python例子,

typedef struct {
char name[20];
int height;
int weight;
} Infor;

不是python对象,是c的结构。要加点料。。。。
如此:
----
Infor* infor;
int res;

if(!PyArg_ParseTuple(args, "siiO:infor", &name, &height, &weight, &infor)){
return NULL;
}
-----
infor 参数是传不进来的。。。。
就说到这。
fengmang_0451 2009-07-27
  • 打赏
  • 举报
回复
大侠们出出手,帮个忙解决一下啊,在此谢过了!
fengmang_0451 2009-07-26
  • 打赏
  • 举报
回复
具体控制台输出信息如下:

[root@localhost obj_struct_test]# ./test.py
Before call getInfor(), Infor.name=NoName Infor.height=-1 Infor.weight=-1
sizeof(*infor)=28, sizeof(Infor)=28
***** [Extest_getInfor] Before Call: infor.name[] infor.height[0] infor.weight[0] *****
[getInfor] get params: name[TestName] height[175] weight[160]
***** [Extest_getInfor] After Call: infor.name[TestName] infor.height[175] infor.weight[160] *****
After call getInfor(), Infor.name=NoName Infor.height=-1 Infor.weight=-1
----- all DONE -----

37,720

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧