Python 访问冲突写入位置0x0000000C
我在为一件事挣扎。我试图通过注入的dll从python api调用游戏函数。它有时可以工作,但通常会抛出一个错误: Soria2.pl.exe中0x1E07F731(python27.dll)处引发异常: 0xC0000005:访问冲突写入位置0x0000000C 以上是来自调试器的日志 我的代码:Python 访问冲突写入位置0x0000000C,python,c++,Python,C++,我在为一件事挣扎。我试图通过注入的dll从python api调用游戏函数。它有时可以工作,但通常会抛出一个错误: Soria2.pl.exe中0x1E07F731(python27.dll)处引发异常: 0xC0000005:访问冲突写入位置0x0000000C 以上是来自调试器的日志 我的代码: std::vector<int> mobList() { PyObject* mod = PyObject_GetAttrString(PyImport_Add
std::vector<int> mobList()
{
PyObject* mod = PyObject_GetAttrString(PyImport_AddModule("player"), "GetCharacterDistance");
PyObject* mod2 = PyObject_GetAttrString(PyImport_AddModule("chr"), "GetInstanceType");
PyObject* args = PyTuple_New(1);
std::vector<int> mobs;
for (int i = 1; i < 100000; i++) {
try {
PyTuple_SetItem(args, 0, PyInt_FromLong(i));
PyObject* mob = PyObject_CallObject(mod, args);
if (PyInt_AsLong(mob) > 0 && PyInt_AsLong(mob) < 400) {
PyObject* enemy = PyObject_CallObject(mod2, args);
if (PyInt_AsLong(enemy) == 0) {
mobs.push_back(i);
}
if (enemy != NULL) {
Py_DECREF(enemy);
}
}
if (mob != NULL) {
Py_DECREF(mob);
}
Py_XDECREF(args);
}
catch (int e) {
std::cout << e << std::endl;
}
}
return mobs;
}
它有时可以工作,但在随机的迭代量(50k、60k、70k等)之后,大多数情况下会抛出上述错误。
我什么都试过了,但还是想不出来:/谢谢你的帮助。我认为@chi是对的:
void Py_DECREF(PyObject*o)
减少对象o的引用计数。对象不能为空;如果不确定它是否为NULL,请使用Py_XDECREF()。如果引用计数达到零,则调用对象类型的释放函数(该函数不得为NULL)
void Py_XDECREF(PyObject*o)
减少对象o的引用计数。对象可能为空,在这种情况下,宏无效;否则,效果与Py_DECREF()相同,并应用相同的警告
警告
deallocation函数可以导致调用任意Python代码(例如,当带有del()方法的类实例被解除分配时)。虽然此类代码中的异常不会传播,但执行的代码可以自由访问所有Python全局变量。这意味着在调用Py_DECREF()之前,可以从全局变量访问的任何对象都应该处于一致状态。例如,从列表中删除对象的代码应该在临时变量中复制对已删除对象的引用,更新列表数据结构,然后为临时变量调用Py_DECREF()
您应该在for循环的之后添加Py\u XDECREF(args)
重新阅读文档时,我看到了一个示例:
arglist = Py_BuildValue("(l)", eventcode);
result = PyObject_CallObject(my_callback, arglist);
Py_DECREF(arglist);
if (result == NULL)
return NULL; /* Pass error back */
/* Here maybe use the result */
Py_DECREF(result);
带着明确的注释:
注意Py_DECREF(arglist)在调用之后、错误检查之前的位置
因此,正如您在一条评论中所说,您可以将args
创建移动到循环中。无关:如果(mob!=NULL){Py_DECREF(mob);}
,只需执行Py_XDECREF(mob)即可代码>访问冲突写入位置0x0000000C
几乎肯定是一个空指针解引用,其中底层关联类型(无论是什么)指定的某些成员变量位于错误消息指定的偏移量处(例如,结构中有12个八位组。无论如何,最好的选择是一个调试器,连接到测试过程中,并允许您的程序吐出整个过程。使用符号构建模块,您甚至可能会得到一个有用的调用堆栈,可追溯到轮子从马车上掉下来的地方。您正在调用pyxdecref(args)
100000次,而args
仍在使用。我不熟悉此API,但这感觉是错误的。投票关闭:第一,否。第二,关于此错误类已经有数百个问题,其中许多问题都有答案和解释。作为这里的新用户,请阅读。@chi我应该在每次迭代中声明args吗ion然后呢?我按照你的建议做了,第一次尝试成功了,但是第二次尝试用同样的行抛出了同样的错误:/
arglist = Py_BuildValue("(l)", eventcode);
result = PyObject_CallObject(my_callback, arglist);
Py_DECREF(arglist);
if (result == NULL)
return NULL; /* Pass error back */
/* Here maybe use the result */
Py_DECREF(result);