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

如何用Swig实现Python datetime对象到C++ DateTime的无缝传递?

实现思路:Python datetime 转 C++ DateTime 结构体的 SWIG Typemap

核心逻辑

要让Python的datetime.datetime对象无缝传入C++函数,需编写SWIG输入typemap,完成两个关键转换:

  1. 从Python datetime对象计算出纪元以来的纳秒数(uint64_t类型)
  2. 将该数值填充到C++的DateTime结构体中

具体实现步骤

1. 编写SWIG Typemap代码

在你的SWIG接口文件(.i)中添加以下typemap:

%typemap(in) DateTime {
    // 校验输入是否为Python datetime对象
    if (!PyDateTime_Check($input)) {
        PyErr_SetString(PyExc_TypeError, "Expected a datetime.datetime object");
        return NULL;
    }

    // 提取datetime的年、月、日等字段
    PyDateTime_DateTime* dt = (PyDateTime_DateTime*)$input;
    int year = PyDateTime_GET_YEAR(dt);
    int month = PyDateTime_GET_MONTH(dt);
    int day = PyDateTime_GET_DAY(dt);
    int hour = PyDateTime_GET_HOUR(dt);
    int minute = PyDateTime_GET_MINUTE(dt);
    int second = PyDateTime_GET_SECOND(dt);
    int microsecond = PyDateTime_GET_MICROSECOND(dt);

    // 构造tm结构体(注意tm_year从1900开始计数,tm_mon从0开始)
    struct tm tm_time = {0};
    tm_time.tm_year = year - 1900;
    tm_time.tm_mon = month - 1;
    tm_time.tm_mday = day;
    tm_time.tm_hour = hour;
    tm_time.tm_min = minute;
    tm_time.tm_sec = second;

    // 转换为epoch秒数
    time_t epoch_sec = mktime(&tm_time);
    if (epoch_sec == -1) {
        PyErr_SetString(PyExc_ValueError, "Invalid datetime value");
        return NULL;
    }

    // 计算总纳秒数:秒数*1e9 + 微秒数*1e3
    uint64_t epoch_ns = (uint64_t)epoch_sec * 1000000000ULL + (uint64_t)microsecond * 1000ULL;

    // 填充到C++ DateTime结构体
    $1.epochns = epoch_ns;
}

// 可选:添加类型检查typemap,让SWIG优先识别datetime对象
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) DateTime {
    $1 = PyDateTime_Check($input) ? 1 : 0;
}

2. 接口文件引入Python datetime依赖

在SWIG接口文件开头添加必要的头文件和声明,确保能调用Python datetime API:

%module your_module_name

// 引入Python datetime支持
%include <pyhead.swg>
%{
#include <Python.h>
#include <datetime.h>
#include <time.h>
#include <stdint.h>

// 你的C++结构体与函数声明
struct DateTime {
    uint64_t epochns;
};
void print(DateTime ts);
%}

// 导出结构体和函数到Python
struct DateTime {
    uint64_t epochns;
};
void print(DateTime ts);

3. 关键注意事项

  • 时区处理:上述代码默认使用本地时区转换,若需处理UTC时间,可将mktime替换为timegm(部分平台需定义_BSD_SOURCE或自行实现UTC转epoch逻辑)。
  • 范围校验:uint64_t能覆盖的时间范围是1970年至约5849年,超出该范围的datetime会导致溢出,需根据业务需求添加额外校验。
  • 编译依赖:编译时需确保编译器能找到Python的头文件与库,链接datetime模块。

4. Python端使用示例

编译生成Python扩展后,即可直接传入datetime对象:

from datetime import datetime
import your_module_name

// 直接调用C++函数,传入datetime对象
your_module_name.print(datetime(1985,7,1))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:50:44