I have to wrap a c library by using python.
After a lot of attempts I am here to ask you for some help. I do not have the c-library code but only the header, so I can post only the python code and the declaration of the two functions I use.
From the header:
//the function that should map the variables
u32 TDO_data_transfer(u32* tdo_arr, u32* tdo_arr_ind, u32* data_struct)
//a function that modifies the arrays and the struct
u32 IR_DR_all_DUTs()
From my Python script:
from ctypes import *
#Simplify wrapping ctypes functions
def wrap_function(lib, funcname, restype, argtypes):
func = lib.__getattr__(funcname)
func.restype = restype
func.argtypes = argtypes
return func
filename = "libIBISGen3.so"
libc = CDLL(filename)
tdo=c_uint32()
tdo_ind=c_uint32()
tdo_arr = pointer(tdo)
tdo_arr_ind = pointer(tdo_ind)
class cerberus_parameter_s(Structure):
_fields_ = [
('opCode', c_uint8),
('bitCount', c_uint16),
('data', c_uint32*32),
('tmsAddress', c_uint8),
('readTDO', c_bool),
('isIR', c_bool),
('dataTDI', c_uint32*32)
]
#create cerberus struct
dt= (c_uint32 * 32)(0)
dtTDI= (c_uint32 * 32)(0)
cerberus= cerberus_parameter_s(0,0,dt,0,0,0,dtTDI)
TDO_data_transfer = wrap_function(libc, 'TDO_data_transfer', c_uint32, [POINTER(c_uint32), POINTER(c_uint32), POINTER(cerberus_parameter_s)])
print(cerberus.readTDO)
print("TDO_data_transfer() returns: ", TDO_data_transfer(tdo_arr, tdo_arr_ind, byref(cerberus)))
print(cerberus.readTDO)
print(cerberus.data[0])
print(tdo_arr[5])
irDrAllDuts = wrap_function(libc, 'IR_DR_all_DUTs', c_uint32,[])
print("IR_DR_all_DUTs() returns: ", irDrAllDuts())
print(cerberus.readTDO)
print(cerberus.data[0])
print(tdo_arr[5])
Output:
TDO_data_transfer() returns: 0
False
0
0
IR_DR_all_DUTs() returns: 50
False
0
0
The last 3 values should be different. I know: I have changed the third argument type in my script to pass the structure, but I don't know how to do it in another way. This is the first problem. At least I should see changes in tdo_arr and tdo_arr_ind after calling IR_DR_all_DUTs() but nothing happens.
As suggested, I post also some parts of the c# code made by my colleague. He made a wrapper and then the script. As long as the struct wasn't well allocated in the memory, he allocated manually every parameter to make the script working, but theoretically, this should not be a problem using ctypes.
C# wrapper:
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace IBISGen3CBFramework
{
public static class libIBIS_Gen3
{
...
public static unsafe class JTagParameter
{
public static byte* OpCode;
public static ushort* BitCount;
public static uint* DataTms;
public static byte* TmsAddress;
public static byte* ReadTdo;
public static byte* IsIr;
public static uint* DataTdi;
public static int GetDataMaxLength()
{
return (int)(((uint)TmsAddress - (uint)DataTms) >> 2);
}
public static void Init(uint* structStartAddress)
{
uint nAddr = (uint)structStartAddress;
OpCode = (byte*)nAddr;
BitCount = (ushort*)(nAddr + 2);
DataTms = (uint*)(nAddr + 4);
TmsAddress = (byte*)(nAddr + 0x84);
ReadTdo = (byte*)(nAddr + 0x85);
IsIr = (byte*)(nAddr + 0x86);
DataTdi = (uint*)(nAddr + 0x88);
}
}
...
[DllImport("libIBIS_Gen3", EntryPoint = "TDO_data_transfer")]
private static extern uint TDO_data_transfer(ref IntPtr resultPtr, ref IntPtr lengthPtr, ref IntPtr structPtr);
public static unsafe void GetResultPointer(out uint* resultArr, out uint* lengthArr, out uint maxLength)
{
IntPtr ptr = new IntPtr();
IntPtr ptr2 = new IntPtr();
IntPtr ptr3 = new IntPtr();
maxLength = TDO_data_transfer(ref ptr, ref ptr2, ref ptr3);
resultArr = (uint*)ptr.ToPointer();
lengthArr = (uint*)ptr2.ToPointer();
JTagParameter.Init((uint*)ptr3.ToPointer());
}
}
}
Is there anyone who could help me, please?
PS: feel free to correct my english in order to make the question clearer.
The following should work (of course not tested):
from ctypes import *
#Simplify wrapping ctypes functions
def wrap_function(lib, funcname, restype, argtypes):
func = lib.__getattr__(funcname)
func.restype = restype
func.argtypes = argtypes
return func
filename = "libIBISGen3.so"
libc = CDLL(filename)
class cerberus_parameter_s(Structure):
_fields_ = [
('opCode', c_uint8),
('bitCount', c_uint16),
('data', c_uint32*32),
('tmsAddress', c_uint8),
('readTDO', c_bool),
('isIR', c_bool),
('dataTDI', c_uint32*32)
]
tdo_arr = POINTER(c_uint32)()
tdo_arr_ind = POINTER(c_uint32)()
cerberus_p = POINTER(cerberus_parameter_s)()
TDO_data_transfer = wrap_function(libc, 'TDO_data_transfer', c_uint32, [POINTER(POINTER(c_uint32)), POINTER(POINTER(c_uint32)), POINTER(POINTER(cerberus_parameter_s))])
print("TDO_data_transfer() returns: ", TDO_data_transfer(byref(tdo_arr), byref(tdo_arr_ind), byref(cerberus_p)))
cerberus = cerberus_p.contents
print(cerberus.readTDO)
print(cerberus.data[0])
print(tdo_arr[5])
irDrAllDuts = wrap_function(libc, 'IR_DR_all_DUTs', c_uint32,[])
print("IR_DR_all_DUTs() returns: ", irDrAllDuts())
print(cerberus.readTDO)
print(cerberus.data[0])
print(tdo_arr[5])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.