【问题标题】:Trouble with DateTime object methods in C++ extensionC++ 扩展中的 DateTime 对象方法的问题
【发布时间】:2018-04-09 05:24:40
【问题描述】:

我正在为 Python 3 开发 C++ 扩展,并尝试将 DateTime 对象传递给我的函数。 PyDateTime_Check 函数似乎可以工作并返回 true,但是当我尝试从 DateTime 对象中获取年份时,它返回 65535。我将 datetime.datetime.now() 从 python 传递给函数。

我的 C++ 代码是:

#include "Python.h"
#include "datetime.h"

static PyObject* new_func(Pyobject* self, PyObject* args)
{
    PyDateTime_DateTime *pydate;
    if(!PyArg_ParseTuple(args, "O", &pydate)){
        return Py_BuildValue("s", "Error");
    }
    int year;
    year = PyDateTime_GET_YEAR(pydate);
    return PyLong_FromLong(year);
}

static PyMethodDef NbourMethods[] =
{
     {"new_func", new_func, METH_VARARGS, "Do date things."},
     {NULL, NULL, 0, NULL}
};

static struct PyModuleDef cFunc =
{
  PyModuleDef_HEAD_INIT,
  "cFunc", /* name of module */
  "",     /* module documentation */
  -1,     /* size of per-interpreter state of the module or -1 if global */
  NbourMethods
};

PyMODINIT_FUNC PyInit_cFunc(void)
{
  if (!PyDateTimeAPI) { PyDateTime_IMPORT;}
  return PyModule_Create(&cFunc);
}

那么我的python代码是:

import cFunc
start = datetime.datetime.now()
print(str(cFunc.new_func(start)))

有什么想法吗?我能够成功运行 PyDateTime_Check(pydate) 并获得返回值为 true,但由于某种原因,它不会在上面的代码中返回年份(返回 65535)。提前致谢!

【问题讨论】:

  • 提取minimal reproducible example。另外,不要在标题中添加标签,而是用几句话概括你的问题。
  • 谢谢,我已经在上面添加了完整的代码。

标签: python c++ python-extensions


【解决方案1】:

所以在搞砸了一些之后,编译器和 python 库似乎都有问题。改变这些产生了预期的结果。我在下面确实有一个奇怪的 hack,但是扩展模块每次加载时都使用了大约 4GB 的 RAM -> 表明发生了更多错误。似乎是 MinGW 中的一个潜在问题。

我原来的解决方案:

所以只是乱七八糟地查看底层的 datetime.h 并进行一些探索——我的日期的 PyObject 中似乎有 4 个字节未使用。不知道为什么会这样。

临时解决方法是通过引用字节 4 和 5(而不是函数中的 0 和 1)返回年份:

year = ((((PyDateTime_Date *)pydate)->data[4] << 8) | ((PyDateTime_Date *)pydate)->data[5]);

这不是很好,但另一种方法是在导入 datetime.h 后定义我自己的 GET_YEAR 函数:

#define PyDateTime_GET_YEAR_NEW(o)     ((((PyDateTime_Date*)o)->data[4] << 8) | \
                 ((PyDateTime_Date*)o)->data[5])

那么函数中的返回可能是:

return PyLong_FromLong(PyDateTime_GET_YEAR_NEW(pydate));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多