Search code examples
pythonpython-2.7ctypesshared-objects

C .so library Python


Now my code works with a normal c library, but I need to use a .so library from Caen and I get Segmentation fault. This is the code:

from ctypes import *
lib = CDLL('./libcaenhvwrapper.so.5.56')
lib.CAENHVInitSystem.restype = c_int
lib.CAENHVInitSystem.argtypes = [c_int, c_int, c_char_p, c_char_p, c_char_p]
lib.CAENHVGetError.restype = c_int    

CAENHV_SYSTEM_TYPE_t = c_int
sy1527 = CAENHV_SYSTEM_TYPE_t(0)
sy2527 = CAENHV_SYSTEM_TYPE_t(1)
sy4527 = CAENHV_SYSTEM_TYPE_t(2)
sy5527 = CAENHV_SYSTEM_TYPE_t(3)
n568 = CAENHV_SYSTEM_TYPE_t(4)
v65xx = CAENHV_SYSTEM_TYPE_t(5)
n1470 = CAENHV_SYSTEM_TYPE_t(6)
v8100 = CAENHV_SYSTEM_TYPE_t(7)

link = c_int
LINKTYPE_TCPIP = link(0)
LINKTYPE_RS232 = link(1)
LINKTYPE_CAENET = link(2)
LINKTYPE_USB = link(3)
LINKTYPE_OPTLINK = link(4)
LINKTYPE_USB_VCP = link(5)

string15=c_char*15
address=string15('1','3','7','.','1','3','8','.','1','3','.','2','0','3','\0')

userName = c_char_p('user')
passwd = c_char_p('user')
ret_init =  lib.CAENHVInitSystem(0, 0, address, userName, passwd)

when I try to call the function I get a segmentation fault. I think the types are correctly defined. Below you can see a piece of code which works ok.

from ctypes import *
lib2 = CDLL('/lib64/libc.so.6')
string15=c_char*15
address=string15('1','3','7','.','1','3','8','.','1','3','.','2','0','3','\0')
address1=create_string_buffer('137.138.13.203')
address2=c_char_p('137.138.13.200')

userName = c_char_p('user')
passwd = c_char_p('user')

a= lib2.strncmp(address, userName, c_int(4))    
a= lib2.strncmp(userName, address, 4)
a= lib2.strncmp(address2, address, 15)

lib2.printf('%d\n', ret_init)
lib2.printf('%s\n', address)
lib2.printf('%s\n', address1)
lib2.printf('%s\n', address2)
lib2.printf('%d\n', lib2.strlen(address))
lib2.printf('%d\n', lib2.strlen(address1))
lib2.printf('%d\n', lib2.strlen(adrress2))

Solution

  • From a quick search:

    CAENHVRESULT CAENHVInitSystem(
    const char *SystemName, // In
    int     LinkType,
    void     *Arg,
    const char *UserName,
    const char *Password
    );
    

    First parameter id definitively a "pointer to char", you should declare it like that:

    lib.CAENHVInitSystem.argtypes = [c_char_p, c_int, c_int, c_char_p, c_char_p, c_char_p]
    

    In addition:

    ret_init =  lib.CAENHVInitSystem(0, 0, address, userName, passwd)
    #                                ^
    

    You pass NULL as SystemName (as NULL is ((void*)0) on most systems). According to the doc I quickly read, this is not explicitly supported.

    This is the first function with parameter SystemName to call, and it must be called for all the HV power supplies the user wants to control