gpt4 book ai didi

c++ - 函数调用时出现 PyObject 段错误

转载 作者:行者123 更新时间:2023-11-30 02:55:43 25 4
gpt4 key购买 nike

我正在尝试使用 Python 打开一个对话框以接受输入到我的 C++ 应用程序中。

这是我正在尝试做的事情的一个非常简单的表示:

#include <iostream>
#include <Python.h>

int main()
{
/* Begin Python Ititialization - only needs to be done once. */
PyObject *ip_module_name = NULL;
PyObject *ip_module = NULL;
PyObject *ip_module_contents = NULL;
PyObject *ip_module_getip_func = NULL;

Py_Initialize();
PyEval_InitThreads();

ip_module_name = PyString_FromString( "get_ip" );
ip_module = PyImport_Import( ip_module_name );
ip_module_contents = PyModule_GetDict( ip_module );
ip_module_getip_func = PyDict_GetItemString( ip_module_contents, "get_ip_address" );
/* End Initialization */

PyGILState_STATE state = PyGILState_Ensure();
PyObject *result = PyObject_CallObject( ip_module_getip_func, NULL );

if( result == Py_None )
printf( "None\n" );
else
printf( "%s\n", PyString_AsString( result ) );

PyGILState_Release( state );

/* This is called when the progam exits. */
Py_Finalize();
}

但是,当我使用 PyObject_CallObject 调用该函数时,应用程序会出现段错误。我猜这是因为我正在使用 Tk 库。我已经尝试将我的应用程序与 _tkinter.lib、tk85.lib、tcl85.lib、tkstub85.lib、tclstub85.lib 相关联,但没有任何帮助。我很困惑...

这是脚本:

import Tkinter as tk
from tkSimpleDialog import askstring
from tkMessageBox import showerror

def get_ip_address():

root = tk.Tk()
root.withdraw()

ip = askstring( 'Server Address', 'Enter IP:' )

if ip is None:
return None

ip = ip.strip()

if ip is '':
showerror( 'Error', 'Please enter a valid IP address' )
return get_ip_address()

if len(ip.split(".")) is not 4:
showerror( 'Error', 'Please enter a valid IP address' )
return get_ip_address()

for octlet in ip.split("."):
x = 0

if octlet.isdigit():
x = int(octlet)
else:
showerror( 'Error', 'Please enter a valid IP address' )
return get_ip_address()

if not ( x < 256 and x >= 0 ):
showerror( 'Error', 'Please enter a valid IP address' )
return get_ip_address()

return ip

编辑:添加我的线程设置

最佳答案

添加 PySys_SetArgv(argc, argv)(连同 int argc, char **argv 参数到 main),您的代码将工作。

tk.Tk() 访问 sys.argv,它不存在,除非调用了 PySys_SetArgv。这会导致异常从 get_ip 传播出去,并通过返回 NULLPyObject_CallObject 报告给 Python/C。 NULL 存储到 result 并传递给 PyString_AsString,这是观察到的崩溃的直接原因。

代码的几点说明:

  • 调试它需要付出努力,因为代码不进行任何错误检查,它盲目地向前推进,直到由于传递 NULL 指针而崩溃。至少一个人可以做的是写这样的东西:

    if (!ip_module_name) {
    PyErr_Print();
    exit(1);
    }
    // and so on for every PyObject* that you get from a Python API call

    在实际代码中,您不会exit(),但会做一些清理并返回NULL(或引发C++ 级异常,或任何适当的)。

  • 无需在已知拥有 GIL 的线程中调用 PyGILState_Ensure。作为documentation of PyEval_InitThreads声明,它初始化 GIL 并获取它。当从 C 回调调用 Python 时,您只需要重新获取 GIL,该回调来自与 Python 无关的工具包事件循环。

  • 从 Python 收到的新引用一旦不再需要,就需要Py_DECREF。为简洁起见,最小示例中可能会省略引用计数,但应始终注意这一点。

关于c++ - 函数调用时出现 PyObject 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16207457/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com