You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用PyDateTime_FromTimestamp触发Segmentation fault问题求助

Segmentation Fault when calling PyDateTime_FromTimestamp in C++ Extension

我之前也踩过这个坑!你遇到的段错误核心原因很明确:没有初始化Python的datetime模块就直接调用了PyDateTime_FromTimestamp。

为什么会出现这个问题?

Python的datetime相关API并不是核心内置API的一部分,它们属于datetime模块的扩展功能。在调用PyDateTime_FromTimestamp这类函数前,必须先完成datetime模块的初始化——否则函数内部依赖的结构体、函数指针都是未绑定的空值,调用时直接访问非法内存,自然触发段错误。

你之前看到timeTuple能正常创建并通过PyTuple_Check检查,是因为Py_BuildValue是Python核心API,不需要依赖额外模块,所以能正常工作,但datetime的API就没这么“省心”了。

修复方案

只需要两步就能解决:

  1. 在模块初始化函数PyInit_cpp中添加PyDateTime_IMPORT();,这个宏会自动帮你完成datetime模块的导入和初始化工作。
  2. 顺便处理下Python对象的引用计数,避免内存泄漏(比如你创建的floatObj和timeTuple用完后要调用Py_DECREF释放)。

修改后的完整代码

#include <python3.6/Python.h>
#include <stdio.h>
#include <python3.6/datetime.h>
#include <sys/time.h>

static PyObject *iGetDateTime_PyFn(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) {
    static double doubleValue = 1314761451;
    PyObject *floatObj = NULL;
    PyObject *timeTuple = NULL;
    PyObject *dateTime = NULL;

    // 创建float对象
    floatObj = PyFloat_FromDouble(doubleValue);
    if (!floatObj) {
        return NULL; // 处理创建失败的情况,Python会自动抛出异常
    }

    // 构建包含float的元组
    timeTuple = Py_BuildValue("(O)", floatObj);
    Py_DECREF(floatObj); // 不再需要floatObj,释放引用计数
    if (!timeTuple) {
        return NULL;
    }

    printf("timeTuple = %08x\n", (unsigned int)(long long)timeTuple);
    printf("PyTuple_Check(timeTuple) = %d\n", PyTuple_Check(timeTuple));

    // 现在可以安全调用datetime API了
    dateTime = PyDateTime_FromTimestamp(timeTuple);
    Py_DECREF(timeTuple); // 释放元组的引用计数

    printf("ready to return\n");
    return dateTime;
}

static PyMethodDef all_methods[] = {
    { "get_datetime", iGetDateTime_PyFn, METH_VARARGS, NULL },
    { NULL, NULL, 0, NULL }
};

static struct PyModuleDef main_module = {
    PyModuleDef_HEAD_INIT,
    "cpp",
    NULL,
    -1,
    all_methods
};

PyMODINIT_FUNC PyInit_cpp(void) {
    // 关键:初始化datetime模块
    PyDateTime_IMPORT();
    return PyModule_Create(&main_module);
}

测试验证

编译命令保持不变:

g++ --shared -fPIC -o cpp.so t1.cpp

在Python中运行:

import cpp
print(cpp.get_datetime())

现在应该能正常输出对应时间戳的datetime对象:2011-08-30 15:30:51,不会再出现段错误了。

内容的提问来源于stack exchange,提问作者Cosmo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:35:51