繁体   English   中英

ctypes.POINTER(ctypes.c_int)和ctypes.c_int * 5有什么区别?

[英]What's the difference between ctypes.POINTER(ctypes.c_int) and ctypes.c_int * 5?

我正在尝试使用ctypes从C ++调用python函数(回调)。 python函数接受一个整数数组作为参数。 我需要在python中访问此数组。

C代码

typedef void (*FooFunc)(int*, int*);
void runfoo(FooFunc foo_func) {
  int dims[5] = {3, 5, 1, 1, 1};
  foo_func(dims, dims);
}

python代码

def foo(dims1, dims2):
    x = dims1[0]
    y = dims1[1]
    z = dims1[2]
    print(x, y, z)
    x = dims2[0]
    y = dims2[1]
    z = dims2[2]
    print(x, y, z)


libc = ctypes.CDLL('./libpath.so')
protofoo = ctypes.CFUNCTYPE(None, ctypes.c_int * 5, ctypes.POINTER(ctypes.c_int))
libc.runfoo(protofoo(foo))

它给出(-333106720、32766,-333106720)(3、5、1)。

原型中的ctypes.c_int * 5和ctypes.POINTER(ctypes.c_int)有什么区别?

ctypes.POINTER(ctypes.int)等效于int*

ctypes.c_int * 5是等效于int arr[5]类型的类型。 它的实现不会像C这样的参数衰减到指针,因此看起来像将其用作参数时,它希望数组按值在堆栈上传递。 我在下面通过在C中以十六进制打印dims地址进行了测试,您可以看到它的64位指针值是显示为十六进制时返回给python的前两个32位元素:

测试

#include <stdio.h>
typedef void (*FooFunc)(int*, int*);
__declspec(dllexport) void runfoo(FooFunc foo_func) {
  int dims[5] = {3, 5, 1, 1, 1};
  printf("%p\n",dims);
  foo_func(dims, dims);
}

test.py

import ctypes

def foo(dims1, dims2):
    x = dims1[0]
    y = dims1[1]
    z = dims1[2]
    print(f'{x:08X} {y:08X} {z:08X}')
    x = dims2[0]
    y = dims2[1]
    z = dims2[2]
    print(f'{x:08X} {y:08X} {z:08X}')

libc = ctypes.CDLL('test')
protofoo = ctypes.CFUNCTYPE(None, ctypes.c_int * 5, ctypes.POINTER(ctypes.c_int))
libc.runfoo(protofoo(foo))

输出量

000000FD6E1EED00
6E1EED00 000000FD 6E1EED00
00000003 00000005 00000001

暂无
暂无

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

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