【问题标题】:Calling call by reference c program in Python program using Ctypes使用 Ctypes 在 Python 程序中通过引用 c 程序调用调用
【发布时间】:2019-10-12 14:33:39
【问题描述】:

我试图在 python 程序中调用 c 交换函数。使用共享对象方法,但我坚持传递python变量地址的地址。

我是python语言的新手,使用的python版本是2.7。

C 程序:

void swap_addr(int *num1, int *num2) {
int temp = *num1;
*num1 = *num2;
*num2 * temp;
}

python 程序:

from ctypes import *

val1 = 10 ;
var2 = 20 ;

lib = cdll.LoadLibrary('./swaplib.so');
lib.swap_addr.argtypes = [c_void_p, c_void_p] ;

Addr_Var1 = POINTER(c_int);
Addr_Var2 = POINTER(c_int);

print ("Before swap val1 and var2 is " + str(var1) + " & " + str(var2))

lib.swap_addr( Addr_Var1(c_int(var1)), Addr_Var2(c_int(var2)) )

print ("After swap val1 and var2 is " + str(var1) + " & " + str(var2))

我希望输出为: 交换之前 val1 和 var2 是 10 & 20 交换后 val1 和 var2 是 20 & 10

但实际输出如下: 交换之前 val1 和 var2 是 10 & 20 交换 val1 和 var2 后为 10 & 20

【问题讨论】:

    标签: python c ctypes


    【解决方案1】:

    当您调用c_int(val1) 时,您正在创建一个新的c_int 对象。此对象包含 C 风格的整数变量。您可以使用byref 轻松获取指向它的指针以进行函数调用。另一方面,Python 的 int 类型是不可变的,并且可能无法修改,即使您确实找到了它的地址;因此val1 和var2 不能交换。所以你的样本应该看起来更像:

    from ctypes import *
    
    var1 = c_int(10)
    var2 = c_int(20)
    
    lib = cdll.LoadLibrary('./swaplib.so')
    lib.swap_addr.argtypes = [c_void_p, c_void_p]
    
    print ("Before swap var1 and var2 is " + str(var1.value) + " & " + str(var2.value))
    
    lib.swap_addr( byref(var1), byref(var2) )
    
    print ("After swap var1 and var2 is " + str(var1.value) + " & " + str(var2.value))
    

    顺便说一句,POINTER 产生一个指针类型,这在您的Addr_Var1 和Addr_Var2 中完全相同。直到您在swap_addr 的参数中创建了它们指向不同位置的类型的值,它们才被立即丢弃(很可能是错误的顺序)。

    【讨论】:

    • 感谢 yann 的快速支持,在 python 程序中更改为 byref 后,我收到错误消息为 AttributeError: 'int' object has no attribute 'byref'
    • 这不是唯一的变化——事实上,它是不太重要的一个。看看var1或var2提到的每个地方。
    • 再次感谢您的支持。现在它按我的预期工作。
    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    相关资源
    最近更新 更多