python - 访问冲突写入位置 0x0000000C
问题描述
我正在为一件事而苦苦挣扎。我正在尝试通过注入的 dll 从 python api 调用游戏的函数。它有时有效,但大多会引发错误:
在 Soria2.pl.exe 中的 0x1E07F731 (python27.dll) 处引发异常:0xC0000005:访问冲突写入位置 0x0000000C
以上是来自调试器的日志。
我的代码:
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;
}
和有问题的部分:
PyObject* mob = PyObject_CallObject(mod, args);
它有时会起作用,但主要是在随机迭代次数(50k、60k、70k 等)后抛出上述错误。我尝试了一切,但仍然无法弄清楚:/感谢任何帮助。
解决方案
我认为@chi 是对的:
无效 Py_DECREF(PyObject *o)
减少对象 o 的引用计数。对象不能为 NULL;如果您不确定它是否为 NULL,请使用 Py_XDECREF()。如果引用计数达到零,则调用对象类型的释放函数(不能为 NULL)。
无效 Py_XDECREF(PyObject *o)
减少对象 o 的引用计数。对象可能为NULL,这种情况下宏不起作用;否则效果与 Py_DECREF() 相同,同样的警告也适用。
警告
释放函数可以导致任意 Python 代码被调用(例如,当具有del () 方法的类实例被释放时)。虽然此类代码中的异常不会传播,但执行的代码可以自由访问所有 Python 全局变量。这意味着在调用 Py_DECREF() 之前,可以从全局变量访问的任何对象都应该处于一致状态。例如,从列表中删除对象的代码应将对已删除对象的引用复制到临时变量中,更新列表数据结构,然后为临时变量调用 Py_DECREF()。
你应该Py_XDECREF(args)
在for
循环之后。
重读文档我看到了一个例子:
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
在循环内移动创作。
推荐阅读
- c# - 在控制台中使用 csc 构建 C# 项目 - 在所有类上出现两个错误
- .net - 无法安装 Umbraco Headless .Net 客户端
- algorithm - 一个包含 100 万个整数的大文件,找到最常出现的整数的最快方法是什么?
- unit-testing - 使用 Spock 测试如何验证 json 属性键值对作为动态输入
- python - CPython:为什么一个 3 行脚本在解释器中需要远远超过 3 个周期才能执行?
- extjs4 - IE上的Extjs 4面板列宽问题
- javascript - 使用 AJAX 加载页面并取消以前的 JavaScript
- javascript - 鼠标移动反方向javascript
- mapbox-gl-js - 使用 mapbox-gl-js 无法正确显示填充挤出
- ios - Fabric 没有向我的仪表板发送数据