python传递指针_使用Python / C API传递C指针

我是Python / C API的新手…我正在尝试为我的C程序添加新功能,其中我可以将python嵌入其中并同时扩展功能,以便嵌入式解释器可以执行将与之交互的脚本作为我的C程序的一部分编写的扩展python模块.我的C程序没有全局变量.我想保持这种方式;同时为了向Cthon公开C功能,看来扩展C函数至少需要访问全局变量来访问程序的状态.我该如何解决这个问题?

例如这是我如何计划嵌入从main调用PYINTERFACE_Initialize的地方

void PYINTERFACE_Initialize(State *ptr, FILE *scriptFile, const char* scriptFileName)

{

Py_Initialize();

PyObject *module = Py_InitModule("CInterface", CInterfaceMethods);

if (PyRun_SimpleFileEx(scriptFile, scriptFileName, 1) != 0)

{

printf("PYINTERFACE script execution failed!\n");

}

**//ADD State *ptr TO module**

}

这是扩展功能:

static PyObject*

CInterface_GetStateInfo(PyObject *self, PyObject *args)

{

const char *printStr;

double stateInfo;

State *ptr;

if(!PyArg_ParseTuple(args, "s", &printStr))

{

return NULL;

}

printf("Received %s\n", printStr);

**//RETRIEVE State *ptr FROM self**

stateInfo = ptr->info;

return Py_BuildValue("d", currentTime);

}

这是通过State * ptr的最干净的方法吗?我当然不认为需要将内部状态暴露给python.我曾考虑使用胶囊,但似乎并不是胶囊的意图支持这种行为.

提前致谢!

V

解决方法:

Capsule基本上是python-opaque void指针,你可以传递或与模块关联.它们是解决问题的“方法”.

这是一个使用不必是静态的实例x的示例.首先将指针指向您的模块,如下所示(删除错误检查)…

// wrap the methods to be exposed to python in a module

// i.e. this is a list of method descriptions for the module

static PyMethodDef InitializeTurkeyMethods[] = {

// this block describes one method.. turkey.do_something()

{"do_something",

turkey_do_something, // fn pointer to wrap (defined below)

METH_VARARGS,

"do something .. return an int."},

{NULL, NULL, 0, NULL} // sentinel.

};

int init(X * x) {

// initialize embedded python scripting ..

// (this method a no-op on second or later calls).

Py_Initialize();

// initialize the turkey python module

PyObject * module = Py_InitModule("turkey", InitializeTurkeyMethods);

// Create a capsule containing the x pointer

PyObject * c_api_object = PyCapsule_New((void *)x, "turkey._X_C_API", NULL);

// and add it to the module

PyModule_AddObject(module, "_X_C_API", c_api_object);

}

然后在你要暴露给python的函数中,为了得到那个X指针,你做了这样的事情(这实际上必须在你开始在上面的代码中引用它之前):

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

if(!PyArg_ParseTuple(args, ":turkey_do_something"))

return NULL;

// get the x pointer back from the capsule

X * x = (X*)PyCapsule_Import("turkey._X_C_API", 0);

// call some fn on x

return Py_BuildValue("i", x->some_fn_that_returns_an_int());

}

这里“turkey._X_C_API”只是一些添加类型检查的名称 – 在这里为您的应用程序添加一些有意义的名称.土耳其是我刚才编写的演示模块名称.

现在假设,并且根据方式,你在调用Py_InitModule()时导出了turkey_do_something fn,你可以从python脚本中调用它:

import turkey

print turkey.do_something()

标签:python,python-c-api

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值