1

I'm making a python app that uses the ctypes library for communicating with a c++ shared library provided by a third-party.

I was provided with a demo c++ program that demonstrates the usage of the shared library, so I'm basically rewriting the c++ code to python/ctypes.

Some functions are working good, but now I keep getting the error

Segmentation fault (core dumped)

on the following code (Specifically on the line that is supposed to make the callback to the python function):

from ctypes import *
LIB_PATH = 'libxxyy.so'

DEFINE1 = 8
DEFINE1_A = (DEFINE1 + 1 + 3) & 0xfffffffc
DEFINE2 = 255
DEFINE2_A = (DEFINE2 + 1 + 3) & 0xfffffffc

class VAR_ENTRY(Structure):
    _fields_ = [
        ('Name', c_char * (DEFINE1_A + DEFINE2_A)),
        ('Format', c_uint16),
        ('Len', c_uint16)
    ]

ListVariablesCallBack = CFUNCTYPE(c_uint8, POINTER(VAR_ENTRY), c_void_p)    #see Update 1 below
@CFUNCTYPE(c_uint8, POINTER(VAR_ENTRY), c_void_p)
def ListVariablesCallBack_func(pvEntry, userParam):
    print("hello from callback")
    # Then read data from pvEntry, add 1 to userParam
    return 0

def MODULE_ListVariables(moduleHandle: c_void_p, cb, userParam: c_void_p) -> c_int32:
    '''
    cb – Callback function to be called for every variable.
    userParam – Parameter, that is passed to callback function.
    '''
    x1lib.MODULE_ListVariables.argtypes = (c_void_p, ListVariablesCallBack, c_void_p)  # See Update 1 below
    x1lib.MODULE_ListVariables.ABCtype = c_int32
    return x1lib.MODULE_ListVariables(moduleHandle, cb, userParam)      # ERROR OCCURS HERE

def browseVariables(targetHandle: c_void_p, moduleName: c_char_p) -> c_int32:
    modHandle = # calculated
    countModules = c_uint32(0)
    ret = MODULE_ListVariables(modHandle, ListVariablesCallBack_func, byref(countModules))
    return

def main():
    targetHandle = # calculated
    browseVariables(targetHandle, c_char_p(b"ABC"))

if __name__ == "__main__":
    x1lib = CDLL(LIB_PATH)
    main()

The cpp demo from which I'm translating from looks like these:

/*
 * <demo.h>
 */
#define CALLBACK

typedef struct
{   
    CHAR8   Name[DEFINE1_A + DEFINE2_A];
    UINT16  Format;
    UINT16  Len;
} VAR_ENTRY;

typedef BOOL8 (CALLBACK *ListVariablesCallBack) (const VAR_ENTRY * varEntry, const VOID* userParam);

X1LIB SINT32 MODULE_ListVariables(M1C_H_MODULE moduleHandle, const ListVariablesCallBack cb, const VOID * userParam); 

/*
 * <demo.cpp>
 */
static BOOL8 CALLBACK listVariablesCallback(const VAR_ENTRY *pvEntry, const VOID *userParam)
{
    UINT32 *countElements = (UINT32 *)userParam;
    (*countElements)++;
    printf("%s\n", pvEntry->Name);
    return true;
}

SINT32 browseVariables(M1C_H_TARGET targetHandle, CHAR8* moduleName)
{
    /* modHandle calculated*/
    UINT32 countModules=0;
    ret = MODULE_ListVariables(modHandle, listVariablesCallback, &countModules);
    return;
}

int main(int argc, char* argv[])
{
    browseVariables(targetHandle, (CHAR8 *)"ABC");
}

What am I doing wrong? (See Update 1)

Sources used (so far): https://docs.python.org/3.3/library/ctypes.html?highlight=ctypes#callback-functions https://stackoverflow.com/a/33485103

Update 1:

So, I've managed to make the script run, by adding the line ListVariablesCallBack = CFUNCTYPE(c_uint8, POINTER(VAR_ENTRY), c_void_p) just above the @CFUNCTYPE(c_uint8, POINTER(VAR_ENTRY), c_void_p) and by setting the argTypes inside the MODULE_ListVariables function to: x1lib.MODULE_ListVariables.argtypes = (c_void_p, ListVariablesCallBack, c_void_p) (I've added the changes in the script above)

Ñhosko
  • 723
  • 2
  • 8
  • 25
  • 2
    Please avoid creating a moving target by adding various updates to the question. Instead, delete it for now and first extract a [mcve] from your code. Then, undelete the question while adding that [mcve]. – Ulrich Eckhardt Apr 27 '21 at 15:52
  • 2
    Also recommend changing that C++ demo to an actual shared library that calls a callback, so building that and running your python script will reproduce the problem. You'll be much more likely to get a solution if we can cut-n-paste C++ source, build it, run your script and reproduce the issue – Mark Tolonen Apr 27 '21 at 21:50
  • Thanks for your feedback. I'll keep in mind the suggestions on future questions. – Ñhosko Apr 28 '21 at 14:59

0 Answers0