首页 > 编程语言 >【C语言调用Python】Py_Finalize() 时报 GC 崩溃错误。

【C语言调用Python】Py_Finalize() 时报 GC 崩溃错误。

时间:2023-12-05 16:22:40浏览次数:27  
标签:Finalize klBool Python Py PROCESS KLP RELEASE NULL

Py_Finalize() 时报 GC 崩溃错误。

记一次有趣的报错随笔。

报错现场

在使用如下的报错代码时,在释放阶段调用Py_Finalize(),报如下Assert崩溃。

原因

结论

在调用函数逻辑里的Exit0中,对变量pModuleDictpClass进行了手动释放,引用计数-1(宏KLP_RELEASE),这两个变量是借用的引用变量,不需要修改引用计数,直接交给Py_Finalize()能够自动回收

修正后的代码只需要删除KLP_RELEASE(pModuleDict);KLP_RELEASE(pClass);即可。

如果其他代码对这两个变量进行了引用计数的增加,才需要手动减少,不然不需要手动释放。

参考:https://stackoverflow.com/questions/6757741/py-finalize-crashes-after-error-in-python

猜想(暴论)

CPython中的Get函数返回的变量都是借用的,不会实际增加引用计数。

报错代码

#define KLP_RELEASE(p) { if (p) { Py_DecRef(p); (p) = NULL; } }

// 调用函数
KL_DLLEXPORT KLcBool KLpePfEyeLaunch()
{
	KLcBool klBool = KL_FALSE;
	PPYOBJECT pModule = NULL;
	PPYOBJECT pModuleDict = NULL;
	PPYOBJECT pClass = NULL;
	PPYOBJECT pClassConstruct = NULL;
	PPYOBJECT pClassIns = NULL;
	PPYOBJECT pClassRet = NULL;

	pModule = PyImport_ImportModule("WizardUltra");
	KLP_PROCESS_ERROR(pModule);

	pModuleDict = PyModule_GetDict(pModule);
	KLP_PROCESS_ERROR(pModuleDict);

	pClass = PyDict_GetItemString(pModuleDict, "CwuKL25COM");
	KLP_PROCESS_ERROR(pClass);

	pClassConstruct = PyInstanceMethod_New(pClass);
	KLP_PROCESS_ERROR(pClassConstruct);

	pClassIns = PyObject_CallObject(pClassConstruct, NULL);
	KLP_PROCESS_ERROR(pClassIns);

	pClassRet = PyObject_CallMethod(pClassIns, "getValue", NULL);
	KLP_PROCESS_ERROR(pClassRet);

	PyArg_Parse(pClassRet, "i", &klBool);
	KLP_PROCESS_ERROR(klBool);

	KLLOG(KLOG_INFO, L"PfEye launch ret: %d", klBool);
	klBool = KL_TRUE;

Exit0:
	KLP_RELEASE(pModule);
    KLP_RELEASE(pModuleDict);
    KLP_RELEASE(pClass);
	KLP_RELEASE(pClassConstruct);
	KLP_RELEASE(pClassIns);
	KLP_RELEASE(pClassRet);
	return klBool;
}

// 释放函数
KL_DLLEXPORT KLcBool KLpUninitPy3(KLPPY3OBJECTLINKCONTAINERDATA_PTR pPy3ObjectData)
{
	KLcBool klBool = KL_FALSE;

	klBool = Py_IsInitialized();
	if (KL_TRUE == klBool)
	{
		Py_Finalize();
	}

	klBool = KL_TRUE;
Exit0:
	return klBool;
}

标签:Finalize,klBool,Python,Py,PROCESS,KLP,RELEASE,NULL
From: https://www.cnblogs.com/hatsuzuki/p/17877499.html

相关文章

  • Python 递归输出树数据 多层级序号
    1.数据结构input_dict={'A':{'B':{'C':{},'D':{}},'E':{'F':{}}},'G':{'H':{},'I':{}}}2.Python代码defco......
  • Python 对树结构数据输出序号(文档目录)层级
    input_data=[{'title':'试验干预中止和参与者退出试验','children':[{'title':'试验干预中止','children':[{'title......
  • Python——第五章:OS模块
    os模块提供了很多允许你的程序与操作系统直接交互的功能importos得到当前工作目录,即当前Python脚本工作的目录路径:os.getcwd()返回指定目录下的所有文件和目录名:os.listdir()函数用来删除一个文件:os.remove()删除多个目录:os.removedirs(r"c:\python")检验给出的路径是......
  • Python (NUDT&&educoder特别关心版)
    Python(NUDT&&educoder特别关心版)主题:浅谈程序设计与算法基础(一份融合IoWiki与educoder实训作业的整理笔记报告)报告人:4p11b彭轩昂(这个不重要)Part1总述与回顾(OverviewandReview)学习Python的优势Python的优点Python是一门解释型语言:Python不需要编......
  • Python闭包概念入门
    '''Python闭包概念入门闭包(Closure)是Python中一个重要的工具。闭包:高阶函数中,内层函数携带外层函数中的参数、变量及其环境,一同存在的状态(即使已经离开了创造它的外层函数),被称之为闭包。被携带的外层变量称之为:自由变量,也被形容为:外层变量被闭包......
  • fileinput:一个txt文件的Python库
    文件处理和输入流时,Python中的fileinput模块是一个非常有用的工具。fileinput模块允许迭代处理多个文件,同时还可以处理标准输入流。以下是Python中fileinput模块的五个常见用法。1.逐行迭代文件fileinput模块可以用于逐行迭代处理文件中的内容。importfileinputforlinei......
  • python在word文件指定的文字下划线
    #coding:utf-8importosfromwin32com.clientimportDispatchdefget_string_index(substring,string):"""获取同一字符串中的多个相同字符串的起始索引:paramsubstring:需查找的字符串:paramstring:被查找的字符串:return:"""in......
  • python第二天
    0.以下哪个变量的命名不正确?为什么?  (A)MM_520  (B)_MM520_  (C)520_MM  (D)_520_MMC,数字不能在首位1.在不上机的情况下,以下代码你能猜到屏幕会打印什么内容吗?>>>myteacher='小甲鱼'>>>yourteacher=myteacher>>>yourteacher='黑夜'>>>print(mytea......
  • 实例讲解Python 解析JSON实现主机管理
    本文分享自华为云社区《Python解析JSON实现主机管理》,作者:LyShark。JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,它以易于阅读和编写的文本形式表示数据。JSON是一种独立于编程语言的数据格式,因此在不同的编程语言中都有对应的解析器和生成器。JSON格式的设计......
  • 【Python/数据库】SQLAlchemy基础操作
    一、SQLAlchemy——创建表#ORM#1.Class-Obj#2.创建数据库引擎#3.将所有的Class序列化为数据表#4.ORM操作-CRUD(增删改查操作的简称)1.创建一个class#create_table.pyfromsqlalchemy.ext.declarativeimportdeclarative_baseBase=declarative_base......