【发布时间】:2014-02-26 22:48:33
【问题描述】:
这在很多地方都有描述,但我根本无法让它工作。我正在从 Cython 调用 C++ 函数:
cimport numpy as np
cdef extern from "test.h" namespace "mytest":
void test(double *A, int m)
cdef int foo():
cdef np.ndarray[double,mode="c"] a = np.array([1,2,3,4,5],dtype=float)
# pass ptr to first element of 'a'
test(&a[0], len(a))
return 0
foo()
test.cpp 只是:
#include <stdio.h>
namespace mytest {
void test(double *A, int m)
{
for (int i = 0; i < m; i++)
{
printf("%d is %f\n", i, A[i]);
}
}
}
test.h 只有:
namespace mytest {
void test(double *A, int m);
}
这似乎可行,但什么时候需要np.ascontiguousarray?这样做就够了吗:
cdef np.ndarray[double,mode="c"] a = np.array([1,2,3,4,5],dtype=float)
或者你需要:
cdef np.ndarray[double,mode="c"] a = np.ascontiguousarray(np.array([1,2,3,4,5],dtype=float))
其次,更重要的是,这如何推广到二维数组?
处理二维数组
这是我将 2d numpy 数组传递给 C++ 的尝试,但它不起作用:
cdef np.ndarray[double,mode="c",ndim=2] a = np.array([[1,2],[3,4]],dtype=float)
称为:
test(&a[0,0], a.shape[0], a.shape[1])
在cpp代码中:
void test(double *A, int m, int n)
{
printf("reference 0,0 element\n");
printf("%f\n", A[0][0]);
}
更新:正确答案
正确的答案是对数组使用线性索引,而不是[][] 语法。打印二维数组的正确方法是:
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%d, %d is %f\n", i, j, A[i*m + j]);
}
}
【问题讨论】:
-
@J.F.Sebastian:谢谢你,我一直在阅读那个帖子,但这让我更加困惑。我基本上是在尝试“&arr[0]”方法,因为它对我来说最有意义,但我还没有看到任何有效的例子。 (我不想使用 ctypes)
-
在您的二维示例中,在我看来,您正在取消引用指针
A两次。对于 2D 数组,您可能必须手动进行索引运算。例如,如果您有一个 C 连续 m x n 数组,并且您想要执行 NumPy 的A[i,j]' you would have to doA[m*i+j]` 的 C 等效项,而不是A[0][0]。两次取消引用指针可能会使 Python 崩溃。 -
m是行数。当您指定指针的类型时,会注意数据类型。我将举一个简单的例子。 -
@user248237dfsf:我很喜欢线程中的建议,使用typed memoryviews (
&s[0]syntax to pass to C)。