Python ctypes和void const指针

时间:2019-05-21 21:39:24

标签: python c++ types ctypes swig

我有一个uint8的numpy数组,我想通过SWIG作为void const指针传递给C ++库。

我使用以下python代码:

<nuxt-link :to="{ name: 'portfolio-slug', params: { slug: card.slug } }">
  <a :href="card.link>Go to href</a>
</nuxt-link>

要在mvIMPACT aquire库中调用ImageDisplay类的SetImage方法:

print(arr.ctypes.data_as(ctypes.c_void_p))
display.GetImageDisplay().SetImage(arr.ctypes.data_as(ctypes.c_void_p),arr.shape[0],arr.shape[1],1,1)
display.GetImageDisplay().Update()

我收到以下错误:

void SetImage   (   const void *    pData,
        int     width,
        int     height,
        int     bitsPerPixel,
        int     pitch 
    )   

我认为pData的类型是错误的。我检查了SWIG包装器,很确定我在调用正确的函数,并且第一个类型匹配

c_void_p(193598576)
Traceback (most recent call last):
  File ".\mvIMPACT test.py", line 137, in <module>
    display.GetImageDisplay().SetImage(arr.ctypes.data_as(ctypes.c_void_p),arr.shape[0],arr.shape[1],1,1)
  File "C:\Program Files (x86)\Python37-32\lib\site-packages\mvIMPACT\acquire.py", line 7101, in SetImage
    def SetImage(self, *args): return lib_mvIMPACT_acquire.ImageDisplay_SetImage(self, *args)
TypeError: in method 'ImageDisplay_SetImage', argument 2 of type 'void const *'
  1. 我的指针不是恒定的,我遇到了问题吗?
  2. 我可以使用ctypes做一个常量指针吗?
  3. 我是否需要使用另一个库复制numpy数组? 我知道一旦我从那个调用返回表格,C ++代码就不会使用数组。

1 个答案:

答案 0 :(得分:1)

我举了一个小例子,说明为什么不能将ctypes.c_void_p与SWIG包装的函数一起使用,并提供了两种替代解决方案。

该示例是针对C库的-对于C ++,您需要查找第一部分的错误名称。

test.h

#pragma once

void SetImage(const void* pData,
              int width,
              int height,
              int hitsPerPixel,
              int pitch);

test.c

#include "test.h"

#include <stdio.h>

void SetImage(const void* pData,
              int width,
              int height,
              int hitsPerPixel,
              int pitch) {
  double* _pData = (double*)pData;
  printf("%f\n",_pData[0]);
}

要编译

swig3.0 -python -includeall -Wall test.i
gcc -shared -o _example.so test.c test_wrap.c -Wall -Wextra -fPIC -I/usr/include/python2.7/ -DSWIGRUNTIME=extern

在Python中,您可以执行以下操作

import ctypes
import example
import numpy as np

arr = np.ones(10,dtype=np.float64)

arg = arr.ctypes.data_as(ctypes.c_void_p)

# Using the C functions
libexample = ctypes.cdll.LoadLibrary("_example.so")

libexample.SetImage(arg, 0,0,0,0)

n = 20
a = example.doubleArray(n)
a[0] = 37.0

# Using the SWIG wrapping
example.SetImage(a,0,0,0,0)