简短回答
NameError 是由于 Python 找不到模块引起的,工作目录并没有自动添加到您的 PYTHONPATH
中。在您的 C/C++
代码中使用 setenv
和 setenv("PYTHONPATH", ".", 1);
可以解决这个问题。
详细回答
有一种简单的方法可以解决这个问题。使用一个包含已创建数组的 Python 模块 pythonmodule.py
:
import numpy as np
result = np.arange(20, dtype=np.float).reshape((2, 10))
您可以使用
public
关键字来构建您的
pymodule.pyx
,以导出该数组。通过添加一些辅助函数,通常情况下,您不需要触及Python或Numpy的
C-API
:
from pythonmodule import result
from libc.stdlib cimport malloc
import numpy as np
cimport numpy as np
cdef public np.ndarray getNPArray():
""" Return array from pythonmodule. """
return <np.ndarray>result
cdef public int getShape(np.ndarray arr, int shape):
""" Return Shape of the Array based on shape par value. """
return <int>arr.shape[1] if shape else <int>arr.shape[0]
cdef public void copyData(float *** dst, np.ndarray src):
""" Copy data from src numpy array to dst. """
cdef float **tmp
cdef int i, j, m = src.shape[0], n=src.shape[1];
tmp = <float **>malloc(m * sizeof(float *))
if not tmp:
raise MemoryError()
for j in range(m):
tmp[j] = <float *>malloc(n * sizeof(float))
if not tmp[j]:
raise MemoryError()
for i in range(m):
for j in range(n):
tmp[i][j] = src[i, j]
dst[0] = tmp
函数getNPArray
和getShape
分别返回数组及其形状。添加了copyData
以便只提取ndarray.data
并将其复制,因此您可以在不初始化解释器的情况下完成Python工作。
以下是一个示例程序(在C
中,C++
应该看起来相同):
#include <Python.h>
#include "numpy/arrayobject.h"
#include "pyxmod.h"
#include <stdio.h>
void printArray(float **arr, int m, int n);
void getArray(float ***arr, int * m, int * n);
int main(int argc, char **argv){
float **data = NULL;
int m, n;
getArray(&data, &m, &n);
printArray(data, m, n);
return 0;
}
void getArray(float ***data, int * m, int * n){
setenv("PYTHONPATH", ".", 1);
Py_Initialize();
initpyxmod();
PyArrayObject *arr = getNPArray();
*m = getShape(arr, 0);
*n = getShape(arr, 1);
copyData(data, arr);
if (data == NULL){
fprintf(stderr, "Data is NULL\n");
return ;
}
Py_DECREF(arr);
Py_Finalize();
}
void printArray(float **arr, int m, int n){
int i, j;
for(i=0; i < m; i++){
for(j=0; j < n; j++)
printf("%f ", arr[i][j]);
printf("\n");
}
}
永远记得进行以下设置:
setenv("PYTHONPATH", ".", 1);
在调用
Py_Initialize
之前,确保Python可以在工作目录中找到模块。
其余部分相当简单。它可能需要一些额外的错误检查,并且绝对需要一个函数来释放已分配的内存。
没有Cython的替代方法:
以您正在尝试的方式完成此操作比它的价值还麻烦,您最好使用
numpy.save
将数组保存在一个
npy
二进制文件中,然后使用一些
C++库为您读取该文件。
Exception NameError: "name 'result' is not defined" in 'pymodule.cfunc' ignored
。 @Jim 我只想传递numpy数组。通常,我有一些在Python上运行的例程很有用,并且希望将结果(通常是numpy数组)传递给更有效的C ++或Fortran代码块,以执行真正需要的计算。一旦这个工作正常,我将编译它成库,在需要时调用它。 - user3225486