问题遇到的现象和发生背景
再写一个东西的mod功能,然后用了python的c/c++SDK,然后开始用得很爽,结果mingw的玄学属实把我吓到了,那个部分的一开始的源代码如下:(用的IDE:Codeblocks 2020 mingw 64 SEH)
问题相关代码,请勿粘贴截图
al("Getting initialized values...");//日志输出函数
///Getting inited values
//outs: #define outs(A) cout << string(#A ":\n") << A << endl;
outs(PyObject_GetAttrString(GetPm().mlcPointer,MENU_STRINGS_ITEM));
showingStrings = getStringLists(PyObject_GetAttrString(GetPm().mlcPointer,MENU_STRINGS_ITEM));
outs(showingStrings[0]);
运行结果及报错内容
这是输出:
[2022-02-09 18:51:56]:652ms:This mod "More Titles" path "C:\Users\yd\AppData\Roaming\XXXX\XXXX\Mods\MT.mtmod"'s OnInit function returns False in python.It loaded fail!
load mod "C:\Users\yd\AppData\Roaming\StudyAll\MineTerraria\Mods\MT.mtmod" fail!
[2022-02-09 18:51:56]:662ms:Getting initialized values...
GetPm().mlcPointer:
0xbcd7268
Process returned -1073741819 (0xC0000005) execution time : 8.593 s
Press any key to continue.
我的解答思路和尝试过的方法
之后我加了两句没有用的话(目的是为了看看python是不是把指针迁移了,导致出现错误),修改代码如下:
al("Getting initialized values...");
///Getting inited values
outs(PyObject_GetAttrString(GetPm().mlcPointer,MENU_STRINGS_ITEM));
outs(PyObject_GetAttrString(GetPm().kernel,"mlc"));//第一句
outs(GetPm().mlcPointer);//第二句
showingStrings = getStringLists(PyObject_GetAttrString(GetPm().mlcPointer,MENU_STRINGS_ITEM));
outs(showingStrings[0]);
结果却出现了玄学情况:
PyObject_GetAttrString(GetPm().mlcPointer,MENU_STRINGS_ITEM):
0
PyObject_GetAttrString(GetPm().kernel,"mlc"):
0xbca7268
GetPm().mlcPointer:
0xbca7268
showingStrings[0]:
Try playing Minecraft!!!!
[2022-02-09 18:55:49]:636ms:Checking mods' logs...
*****************************************************
[2022-02-09 18:55:49]:646ms:Here are the mod logs that are listed:
''
*****************************************************
它竟然没崩掉!
我想要达到的结果
我只是想知道这是为什么(我还尝试了Py_Incref(GetPm().mlcPointer)与Py_Decref(GetPm().mlcPointer)来看看是不是引用的问题,然而,很可惜,崩溃了,应该不是内存引用的问题)
######崩溃的外在原因
以下是加载的"模组"python代码:
# 这个是api,还没上高中,英语不好,许多英语句子语法不对,勿喷
# mtmod_loader.py
'''
Import Suggestions:
from mtmod_loader import *
Using Docs:
Loading dods has many steps
While in version 1.0,it has only 1 step:
Initializing
Initializing:
To init,you need to have a function OnInit()
'''
# We suggest you not to change mlc directly
class ModLoaderConfig:
#Strings that shows on the menu
menuStrings = []
# Very Warning:Do not change this value,or mod loading proc will fail!
# now loading proc!DO NOT CHANGE IT!!THIS IS VERY IMPORTANT DATA
nowProc = 0
# the mod's log
modLog = ''
#the statuses
menuLock = False
'''
The Manifest file's attributes
You can easily get them
'''
class ManifestFileSets:
# Mod Name
ModName = ""
# This Mod's Version
ModVersion = ""
# The Mod's Creator
ModAuthor = ""
# The Mod's Description
ModDescription = ""
# The Only Package ID,Make sure this id is the only one!!!!
ModPackage = ""
mlc = ModLoaderConfig()
mf = ManifestFileSets()
apiVersion = "api-1.0"
MenuLocked = 2
NowIsNotIniting = 1
Suc = 0
Fail = -1
'''
Lock the menu,other mods cannot change menuString if they follows the usual steps
'''
def lockMenu():
mlc.menuLock = True
'''
Set the strings shows upon the menu
'''
def setMenuString(menuStr):
if(mlc.menuLock):
return MenuLocked
if(mlc.nowProc == 0):
mlc.menuStrings = menuStr
return Suc
else:
return NowIsNotIniting
def sms(menuStr):
return setMenuString(menuStr)
'''
Append the strings that shows on the menu
'''
def appendMenuString(nstr):
mlc.menuStrings.append(str(nstr))
def ams(nstr):
appendMenuString(nstr)
'''
Get the strings that shows on the menu
'''
def getMenuString():
return mlc.menuStrings
def gms():
return mlc.menuStrings
'''
Get the loading proc now
'''
def getLoadingProcess():
return mlc.nowProc
def glp():
return mlc.nowProc
'''
Write the program log
'''
def writeModLog(strlg):
mlc.modLog += str(strlg)
def wml(strlg):
writeModLog(strlg)
这个是模组的代码
# main.py
from mtmod_loader import *
def OnInit():
print('Initializing mod',mf.ModName);
l = getMenuString()
l.append("More Titles is a mod which adds a lots titles to the main menu screen!")
l.crashDump() #list中没有这个成员,这个是专门测试崩溃的
setMenuString(l)
print(getMenuString())
print('Done initializing mod',mf.ModName);
return False