Вызов вызова по ссылке c программой в программе Python с использованием Ctypes - PullRequest
1 голос
/ 12 октября 2019

Я пытаюсь вызвать функцию подкачки c в программе на Python. Использование метода общего объекта, но я застрял, чтобы передать адрес переменной адреса 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

1 Ответ

0 голосов
/ 12 октября 2019

Когда вы вызываете 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, и они были немедленно отброшены (вполне возможно, в неправильном порядке).

...