繁体   English   中英

是否可以通过 Ctypes 使用指向 3dim 数组的指针调用 C DLL?

[英]Is it possible to call a C DLL with a pointer to a 3dim array via Ctypes?

问题
是否可以通过 Ctypes 使用指向 3dim 数组的指针调用 C DLL?

进步
首先,我对 C 和 DLL 很陌生,所以我可能不知道/监督过一些琐碎的事情。
我已经让它运行一个指向 1dim 数组的指针。 但是,能够使用 3dim 数组真的很好,因为我想操作 RGB 图像数据,这确实需要边缘重复。

Python代码

import ctypes
import ctypes.util
from numpy.ctypeslib import ndpointer
import PBMS_ImageIO
import numpy as np

#Loads a image as 3dim array and converts it to 1dim array with "size" as length
image = PBMS_ImageIO.readImage('Image.png')
size = np.shape(image)[0]*np.shape(image)[1]*np.shape(image)[2]
imageIn = np.reshape(image, (size,))

PBMS_ImageConverter = ctypes.windll.LoadLibrary(ctypes.util.find_library('./PBMS_ImageConvert.dll'))

nd_pointer = np.ctypeslib.ndpointer(dtype=np.float32, ndim=1, flags=("C"))
PBMS_ImageConverter.RGB2BW.argtypes=[nd_pointer, ctypes.c_int]
PBMS_ImageConverter.RGB2BW.restype = ndpointer(dtype=ctypes.c_float,
                                               shape=(size,))
imageOut = PBMS_ImageConverter.RGB2BW(imageIn, size)

C代码

#include <math.h>

float * RGB2BW(const float * matrixIn, int size)
{
    float * matrixOut = (float *)malloc(sizeof(float)*size);
    for(int i = 0; i < size; i++)
    {
        matrixOut[i] = matrixIn[i];
    }
    return matrixOut;
}

选择
如果通过 Ctypes 调用 DLL 不能使用 3dim 指针,是否可以在内部将 1dim 数组转换为 3dim 数组?

不确定
我也不确定 numpy 数组是如何存储在 memory 中的。 可能是因为底层的 numpy 数组并未真正存储为 3dim,因此我将指针传递给 3dim 数组的努力没有成功吗?

Numpy arrays are stored in the same memory orientation as C arrays by default. On the Python side you can work with 3D arrays, but it's easier on the C side to treat as a 1D array and do the math to access rows and columns.

下面的示例需要 3D numpy 数组作为参数,但传递维度以便 C 代码可以访问元素。 C 代码就地修改数组:

测试.c

#include <stdio.h>

__declspec(dllexport)
void RGB2BW(float* matrix, int x, int y, int z)
{
    for(int i = 0; i < x; ++i)
        for(int j = 0; j < y; ++j)
            for(int k = 0; k < z; ++k)
            {
                int index = i * y * z + j * z + k;
                printf("matrix[%d][%d][%d] = %f\n",i,j,k,matrix[index]);
                matrix[index] *= 2;
            }
}

测试.py

import numpy as np
from ctypes import *

dll = CDLL('./test')
dll.RGB2BW.argtypes = np.ctypeslib.ndpointer(dtype=np.float32,ndim=3),c_int,c_int,c_int
dll.RGB2BW.restype = None

a = np.arange(0,2.4,.1,dtype=np.float32).reshape(2,3,4)
dll.RGB2BW(a,*a.shape)
print(a)

Output:

matrix[0][0][0] = 0.000000
matrix[0][0][1] = 0.100000
matrix[0][0][2] = 0.200000
matrix[0][0][3] = 0.300000
matrix[0][1][0] = 0.400000
matrix[0][1][1] = 0.500000
matrix[0][1][2] = 0.600000
matrix[0][1][3] = 0.700000
matrix[0][2][0] = 0.800000
matrix[0][2][1] = 0.900000
matrix[0][2][2] = 1.000000
matrix[0][2][3] = 1.100000
matrix[1][0][0] = 1.200000
matrix[1][0][1] = 1.300000
matrix[1][0][2] = 1.400000
matrix[1][0][3] = 1.500000
matrix[1][1][0] = 1.600000
matrix[1][1][1] = 1.700000
matrix[1][1][2] = 1.800000
matrix[1][1][3] = 1.900000
matrix[1][2][0] = 2.000000
matrix[1][2][1] = 2.100000
matrix[1][2][2] = 2.200000
matrix[1][2][3] = 2.300000
[[[0.        0.2       0.4       0.6      ]
  [0.8       1.        1.2       1.4      ]
  [1.6       1.8000001 2.        2.2      ]]

 [[2.4       2.6000001 2.8       3.       ]
  [3.2       3.4       3.6000001 3.8      ]
  [4.        4.2000003 4.4       4.6      ]]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM