从C扩展API的python回调访问全局变量
我不熟悉python和C扩展。我正在编写一个python代码,其中创建了两个线程,并定义了一个回调函数py_cb()。 在一个线程中,我在特定的时间间隔后附加到一个全局列表,而在另一个线程中,我调用一个C扩展库api。C扩展api生成一个线程,该线程调用在我的原始文件中定义的python回调函数(py_cb)。在回调函数中,我试图显示全局列表,但它似乎有不同的id。我使用id(listName)检查了它。有没有办法在C扩展python回调函数中使用正确的全局变量?我假设全局值将在所有线程之间共享,不是吗?另外,请提出更好的解决方案 以下是C代码:从C扩展API的python回调访问全局变量,python,callback,python-c-extension,python-extensions,Python,Callback,Python C Extension,Python Extensions,我不熟悉python和C扩展。我正在编写一个python代码,其中创建了两个线程,并定义了一个回调函数py_cb()。 在一个线程中,我在特定的时间间隔后附加到一个全局列表,而在另一个线程中,我调用一个C扩展库api。C扩展api生成一个线程,该线程调用在我的原始文件中定义的python回调函数(py_cb)。在回调函数中,我试图显示全局列表,但它似乎有不同的id。我使用id(listName)检查了它。有没有办法在C扩展python回调函数中使用正确的全局变量?我假设全局值将在所有线程之间共享
char *MODULE_NAME = "simple";
---
PyMODINIT_FUNC init_cmodule(void)
{
PyObject *m = Py_InitModule3("_cmodule",module_methods,module_docstring);
if (m == NULL)
return;
}
static PyObject *cmodule_cmodule(PyObject *self, PyObject *args)
{
int value = register_cb();
PyObject *ret = Py_BuildValue("i",value);
return ret;
}
void notifyFooHandle()
{
printf("inside the notify_foo function\n");
pModule = PyImport_ImportModule(MODULE_NAME);
if (!pModule) {
printf ("Failed to load the module\n");
return;
}
PyObject *pFunc;
pFunc = PyObject_GetAttrString(pModule, "py_cb");
if (pFunc && PyCallable_Check(pFunc)) {
PyObject_CallObject(pFunc,NULL);
}
else {
Py_DECREF(pFunc);
PyErr_Print();
printf("Failed to send notification\n");
return;
}
return;
}
void notify_foo(void)
{
int t = 5;
while (t < 10) {
notifyFooHandle();
sleep(5);
t++;
}
return;
}
int register_cb(void)
{
pthread_t notify_t;
int rc = pthread_create(¬ify_t, NULL, (void *) ¬ify_foo,NULL);
---
}
你能给我们看看你的C库中的代码吗?如果您在那里初始化一个python虚拟机,然后调用py_cb,那么很容易理解为什么列表不同:您有两个不同的python虚拟机实例 编辑: 我认为您的问题在于您使用的是两个不同的python实例。首先,您的主程序是用python编写的。在该实例中,您有一个全局“myList”,因此从该实例调用的每个函数都将访问“myList”的特定实例。然后,加载一个C模块。当该C模块打开原始python模块以加载py_cb时,您使用的是另一个python实例,您将有第二个“myList”。简而言之,有两个不同的python实例正在运行,一个是在运行主python脚本时创建的,另一个是在C库中创建的,用于调用py_cb
如果你想共享一个公共python实例,你必须在C中创建你的实例,使它在你的C模块中全局可访问,在那里插入你的C函数,然后运行你的主python函数。当python调用C函数时,您将处于原始地址空间内,而不是新的地址空间,当您调用python时,您将始终使用同一个python实例。我修改了这个问题,将C代码和python回调api片段包括在内。我想您的问题正是我所怀疑的。每次调用“notifyfoodhandle”时,您都会加载模块,获取一个py_cb函数处理程序并调用它,但您并不是在python调用程序中调用py_cb,而是在一个完全不同的python实例中调用py_cb。你必须采取完全不同的方法。我将试着在我的回答中解释。
def py_cb():
print "Received a call back from cmodule"
global myList
print "Global myList is ", id(myList)
print myList
return