gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 18:00:29 25 4
gpt4 key购买 nike

我是 Python/C API 的新手...我正在尝试向我的 C 程序添加新功能,我可以在其中嵌入 python 并同时扩展功能,以便嵌入式解释器可以执行脚本将与作为我的 C 程序的一部分编写的扩展 python 模块进行交互。我的 C 程序没有全局变量。我想保持这种状态;同时,为了向 python 公开 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

最佳答案

胶囊基本上是 python 不透明的空指针,您可以传递它们或与模块关联。它们是解决您问题的“方法”。

这是一个使用实例 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”只是一些附加类型检查的名称 - 在这里为您的应用输入一些有意义的名称。 Turkey是我刚才编的一个demo模块名。

现在假设在调用 Py_InitModule() 时您已经导出了 turkey_do_something fn,这取决于您如何从 python 脚本中这样调用它:

import turkey

print turkey.do_something()

检查这个:http://docs.python.org/2/c-api/arg.html关于如何格式化元组和这个.. http://docs.python.org/3.1/c-api/capsule.html对于胶囊上的 doco

关于python - 使用 Python/C API 传递 C 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8436578/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com