python ctypes 指针,Python Ctypes传递数据指针

I am accessing an API and can't get the data returned. The two float pointers will point to an array of data. I must assume the API is working properly. A different function call provides a the length of the data I am retrieving. This values is length down below when attempted.

C Header for Function

int function(int, float * data1, float * data2)

ctypes setup

dll.function.argtypes = (c_int, POINTER(c_float), POINTER(c_float))

dll.function.restypes = c_int

Failed Attempt 1:

x = c_float()

y = c_float()

status = dll.function(1, byref(x), byref(y))

Program crashes OR Access violation writing.

Failed Attempt 2:

x = POINTER(c_float)()

y = POINTER(c_float)()

status = dll.function(1, x, y)

Null Pointer Error

Failed Attempt 3:

dll.function.argtypes = (c_int, c_void_p, c_void_p)

x = c_void_p()

y = c_void_p()

status = dll.function(1, x, y)

Null Pointer Error

Failed Attempt 4:

array = c_float * length

x = array()

y = array()

status = dll.function(1, byref(x), byref(y))

Program crashes

Failed Attempt 5:

array = c_float * length

x = POINTER(array)()

y = POINTER(array)()

status = dll.function(1, x, y)

Null Pointer Error OR ArgumentError: expected LP_c_float instance instead of LP_c_float_Array_[length]

Failed Attempt 6:

x = (c_float*length)()

y = (c_float*length)()

a = cast(x, POINTER(c_float))

b = cast(y, POINTER(c_float))

status = dll.function(1, a, b)

Program crashes

What am I missing and why?

I believe the argtypes are correct. I am attempting to meet them properly, but there continues to be an issues. Do I need to "malloc" the memory somehow? (I'm sure I need to free after I get the data).

This is on Windows 7 with Python 2.7 32-bit.

I have looked through other similar issues and am not finding a solution. I am wondering if, at this point, I can blame the API for this issue.

解决方案

Dealing with pointers and arrays is explained in [Python 3]: Type conversions.

I prepared a dummy example for you.

main.c:

#if defined(_WIN32)

# define DECLSPEC_DLLEXPORT __declspec(dllexport)

#else

# define DECLSPEC_DLLEXPORT

#endif

static int kSize = 5;

DECLSPEC_DLLEXPORT int size() {

return kSize;

}

DECLSPEC_DLLEXPORT int function(int dummy, float *data1, float *data2) {

for (int i = 0; i < kSize; i++) {

data1[i] = dummy * i;

data2[i] = -dummy * (i + 1);

}

return 0;

}

code.py:

#!/usr/bin/env python

import sys

import ctypes

c_float_p = ctypes.POINTER(ctypes.c_float)

def main():

dll_dll = ctypes.CDLL("./dll.so")

size_func = dll_dll.size

size_func.argtypes = []

size_func.restype = ctypes.c_int

function_func = dll_dll.function

function_func.argtypes = [ctypes.c_int, c_float_p, c_float_p]

function_func.restype = ctypes.c_int

size = size_func()

print(size)

data1 = (ctypes.c_float * size)()

data2 = (ctypes.c_float * size)()

res = function_func(1, ctypes.cast(data1, c_float_p), ctypes.cast(data2, c_float_p))

for i in range(size):

print(data1[i], data2[i])

if __name__ == "__main__":

print("Python {:s} on {:s}\n".format(sys.version, sys.platform))

main()

Notes:

The C part tries to mimic what your .dll does (or at least what I understood):

size - gets the arrays sizes

function - populates the arrays (till their size - assuming that they were properly allocated by the caller)

Python part is straightforward:

Load the .dll

Define argtypes and restype (in your code it's restype's) for the 2 functions (for size_func not necessary)

Get the lengths

Initialize the arrays

Pass them to function_func using ctypes.cast

Output (on Lnx, as building the C code is much simpler, but works on Win as well):

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> gcc -shared -o dll.so main.c

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> python3 code.py

Python 3.5.2 (default, Nov 23 2017, 16:37:01)

[GCC 5.4.0 20160609] on linux

5

0.0 -1.0

1.0 -2.0

2.0 -3.0

3.0 -4.0

4.0 -5.0

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值