【问题标题】:passing c++ double pointer to python将 c++ 双指针传递给 python
【发布时间】:2012-02-05 16:27:28
【问题描述】:

我可以将一维数组传递给 python,如下所示。 我想知道我是否可以通过使用 ctypes、numpy 将 c++ 双指针数组传递给 python。

test.cpp:

#include <stdio.h>
extern "C" void cfun(const void * indatav, int rowcount, int colcount, void * outdatav);

void cfun(const void * indatav, int rowcount, int colcount, void * outdatav) {
    //void cfun(const double * indata, int rowcount, int colcount, double * outdata) {
    const double * indata = (double *) indatav;
    double * outdata = (double *) outdatav;
    int i;
    puts("Here we go!");
    for (i = 0; i < rowcount * colcount; ++i) {
        outdata[i] = indata[i] * 4;
    }
    puts("Done!");
}

test.py:

import numpy
import ctypes

indata = numpy.ones((5,6), dtype=numpy.double)
outdata = numpy.zeros((5,6), dtype=numpy.double)
lib = ctypes.cdll.LoadLibrary('./ctest.so')
fun = lib.cfun
# Here comes the fool part.
#fun(ctypes.c_void_p(indata.ctypes.data), ctypes.c_void_p(outdata.ctypes.data))

fun(ctypes.c_void_p(indata.ctypes.data), ctypes.c_int(5), ctypes.c_int(6),
    ctypes.c_void_p(outdata.ctypes.data))


print 'indata: %s' % indata
print 'outdata: %s' % outdata

【问题讨论】:

  • 这是我学过的一个技巧,但为什么不将指针作为长整数传递呢?
  • 因为类型可以是 double.. 等等,不仅是整数。
  • 指针总是可以表示为长整数。然后转换回你想要的任何类型。

标签: python numpy ctypes cython f2py


【解决方案1】:

这是一种方法。我没有看到将 numpy 与 double** 结合使用的好方法。

test.cpp (Windows)

#include <stdio.h>

extern "C" __declspec(dllexport) void cfun(const double ** indata, int rowcount, int colcount, double ** outdata) {
    for (int i = 0; i < rowcount; ++i) {
        for (int j = 0; j < colcount; ++j) {
            outdata[i][j] = indata[i][j] * 4;
        }
    }
}

test.py

import numpy
import ctypes

# Allocate array of double*
indata = (ctypes.POINTER(ctypes.c_double) * 5)()
for i in range(5):
    # Allocate arrays of double
    indata[i] = (ctypes.c_double * 6)()
    for j in range(6):
        indata[i][j] = 1.0

outdata = (ctypes.POINTER(ctypes.c_double) * 5)()
for i in range(5):
    outdata[i] = (ctypes.c_double * 6)()
    for j in range(6):
        outdata[i][j] = 1.0

lib = ctypes.cdll.LoadLibrary('test')
fun = lib.cfun

def dump(a,rows,cols):
    for i in range(rows):
        for j in range(cols):
            print a[i][j],
        print

dump(indata,5,6)
fun(ctypes.byref(indata),5,6,ctypes.byref(outdata))
dump(outdata,5,6)

输出

1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0
4.0 4.0 4.0 4.0 4.0 4.0
4.0 4.0 4.0 4.0 4.0 4.0
4.0 4.0 4.0 4.0 4.0 4.0
4.0 4.0 4.0 4.0 4.0 4.0
4.0 4.0 4.0 4.0 4.0 4.0

【讨论】:

  • 我在创建“.so”文件 test.cpp:4:1 时出错:错误:预期的构造函数、析构函数或在“(”标记之前的类型转换
  • 没有“__declspec(dllexport)”也能正常工作。谢谢,在fortran中,多维数组可以直接用numpy传递吗? fwrap .. 实际上我正在寻找在 python c,c++ fortran. 之间传递数组
  • 是的,__declspec(dllexport) 是特定于 Windows 的,用于从动态库中导出函数。您发布的代码使用双指针和多维数组按原样工作(对我来说,使用 Windows 的次要模块)。不过,您不需要所有的演员表。你的问题到底是什么?
  • 我已经很多年没有接触过 Fortran,所以对此无能为力。我会注意到,如果您使用 double* 而不是 void* 编写原始 C++ 函数,则可以直接传递 _____.ctypes.data 而无需 ctypes.c_void_p 包装器。你也可以通过5,6 而不是ctypes.c_int(5),ctypes.c_int(6)
  • 有没有办法通过使用 numpy 来传递这个数组?我想使用 numpy 不仅使用 ctypes。
猜你喜欢
  • 2011-05-19
  • 2020-05-29
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多