长 int* 到 np_intp* 取决于平台的转换

long int* to np_intp* platform dependent conversion

本文关键字:取决于 平台 intp 转换 int np      更新时间:2023-10-16

在我的 64 位办公桌面上,这编译得很好:

#include <Python.h>
#include <numpy/arrayobject.h>
...
Py_Initialize();
import_array();
// Build array object
long int NUMEL=3;
PyObject *out_array = PyArray_SimpleNew(1, &NUMEL, NPY_DOUBLE);

相反,在我的 32 位笔记本电脑上,这失败了,产生错误:

 error: invalid conversion from ‘long int*’ to ‘npy_intp* {aka int*}’ [-fpermissive]
     PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)

或者,如果我声明int NUMEL=3,代码将在 32 位机器上编译,但不在 64 位机器上编译。我怀疑npy_intp依赖于平台。由于我无法定义npy_intp类型的NUMEL(因为实际上它是由其他仅 C/C++ 例程传递的),有没有办法根据C++代码中的平台有条件地定义NUMEL

npy_intp在这里

typedef

typedef Py_intptr_t npy_intp;

Py_intptr_t是在 pyport.h 年的 Python C 源代码中定义的。 它高度依赖于系统,有关详细信息,请参阅该源代码,但在大多数情况下,除非您正在处理Microsoft的Visual C是C89,否则您必须stdint.h并且可以简单地包含它并使用intptr_t作为您的类型。 C++这std::ptrdiff_t,也看看它的未签名对应物,std::size_t

作为最后的手段,你总是可以复制Python所做的,如下所示:

#if sizeof(void *) <= sizeof(int)
    typedef int my_type;
#elif sizeof(void *) <= sizeof(long)
    typedef long my_type;
#else
    typedef long long my_type;
#endif

几乎适用于所有平台,尽管您可能会发现它不能移植到同一个奇怪的角落案例系统。