• Help on ctypes.POINTER for Python array

    From Jason Qian@21:1/5 to All on Thu May 11 10:59:01 2023
    Hi,

    Need some help,

    in the Python, I have a array of string

    var_array=["Opt1=DG","Opt1=DG2"]

    I need to call c library and pass var_array as parameter

    In the argtypes, how do I set up ctypes.POINTER(???) for var_array?

    func.argtypes=[ctypes.c_void_p,ctypes.c_int, ctypes.POINTER(????)]

    In the c code:

    int func (void* obj, int index, char** opt)

    Thanks
    Jason

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jim Schwartz@21:1/5 to All on Thu May 11 10:15:47 2023
    I’m not sure this is the shortest method, but you could set up two python scripts to do the same thing and convert them to c using cython. I wouldn’t be able to read the c scripts, but maybe you could.

    Maybe someone else has a more direct answer.

    Sent from my iPhone

    On May 11, 2023, at 10:00 AM, Jason Qian via Python-list <python-list@python.org> wrote:

    Hi,

    Need some help,

    in the Python, I have a array of string

    var_array=["Opt1=DG","Opt1=DG2"]

    I need to call c library and pass var_array as parameter

    In the argtypes, how do I set up ctypes.POINTER(???) for var_array?

    func.argtypes=[ctypes.c_void_p,ctypes.c_int, ctypes.POINTER(????)]

    In the c code:

    int func (void* obj, int index, char** opt)

    Thanks
    Jason
    --
    https://mail.python.org/mailman/listinfo/python-list

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Eryk Sun@21:1/5 to Jason Qian via Python-list on Thu May 11 12:47:50 2023
    On 5/11/23, Jason Qian via Python-list <python-list@python.org> wrote:

    in the Python, I have a array of string
    var_array=["Opt1=DG","Opt1=DG2"]
    I need to call c library and pass var_array as parameter
    In the argtypes, how do I set up ctypes.POINTER(???) for var_array?

    func.argtypes=[ctypes.c_void_p,ctypes.c_int, ctypes.POINTER(????)]

    In the c code:
    int func (void* obj, int index, char** opt)

    The argument type is ctypes.POINTER(ctypes.c_char_p), but that's not sufficient. It doesn't implement converting a list of str objects into
    an array of c_char_p pointers that reference byte strings. You could
    write a wrapper function that implements the conversion before calling
    func(), or you could set the argument type to a custom subclass of ctypes.POINTER(ctypes.c_char_p) that implements the conversion via the from_param() class method.

    https://docs.python.org/3/library/ctypes.html#ctypes._CData.from_param

    Here's an example of the latter.

    C library:

    #include <stdio.h>

    int
    func(void *obj, int index, char **opt)
    {
    int length;
    for (length=0; opt[length]; length++);
    if (index < 0 || index >= length) {
    return -1;
    }
    return printf("%s\n", opt[index]);
    }


    Python:

    import os
    import ctypes

    lib = ctypes.CDLL('./lib.so')
    BaseOptions = ctypes.POINTER(ctypes.c_char_p)

    class Options(BaseOptions):
    @classmethod
    def from_param(cls, param):
    if isinstance(param, list):
    new_param = (ctypes.c_char_p * (len(param) + 1))()
    for i, p in enumerate(param):
    new_param[i] = os.fsencode(p)
    param = new_param
    return BaseOptions.from_param(param)

    lib.func.argtypes = (ctypes.c_void_p, ctypes.c_int, Options)


    demo:

    >>> opts = ['Opt1=DG', 'Opt1=DG2']
    >>> lib.func(None, 0, opts)
    Opt1=DG
    8
    >>> lib.func(None, 1, opts)
    Opt1=DG2
    9

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jason Qian@21:1/5 to eryksun@gmail.com on Thu May 11 13:58:33 2023
    Awesome, thanks!

    On Thu, May 11, 2023 at 1:47 PM Eryk Sun <eryksun@gmail.com> wrote:

    On 5/11/23, Jason Qian via Python-list <python-list@python.org> wrote:

    in the Python, I have a array of string
    var_array=["Opt1=DG","Opt1=DG2"]
    I need to call c library and pass var_array as parameter
    In the argtypes, how do I set up ctypes.POINTER(???) for var_array?

    func.argtypes=[ctypes.c_void_p,ctypes.c_int, ctypes.POINTER(????)]

    In the c code:
    int func (void* obj, int index, char** opt)

    The argument type is ctypes.POINTER(ctypes.c_char_p), but that's not sufficient. It doesn't implement converting a list of str objects into
    an array of c_char_p pointers that reference byte strings. You could
    write a wrapper function that implements the conversion before calling func(), or you could set the argument type to a custom subclass of ctypes.POINTER(ctypes.c_char_p) that implements the conversion via the from_param() class method.

    https://docs.python.org/3/library/ctypes.html#ctypes._CData.from_param

    Here's an example of the latter.

    C library:

    #include <stdio.h>

    int
    func(void *obj, int index, char **opt)
    {
    int length;
    for (length=0; opt[length]; length++);
    if (index < 0 || index >= length) {
    return -1;
    }
    return printf("%s\n", opt[index]);
    }


    Python:

    import os
    import ctypes

    lib = ctypes.CDLL('./lib.so')
    BaseOptions = ctypes.POINTER(ctypes.c_char_p)

    class Options(BaseOptions):
    @classmethod
    def from_param(cls, param):
    if isinstance(param, list):
    new_param = (ctypes.c_char_p * (len(param) + 1))()
    for i, p in enumerate(param):
    new_param[i] = os.fsencode(p)
    param = new_param
    return BaseOptions.from_param(param)

    lib.func.argtypes = (ctypes.c_void_p, ctypes.c_int, Options)


    demo:

    >>> opts = ['Opt1=DG', 'Opt1=DG2']
    >>> lib.func(None, 0, opts)
    Opt1=DG
    8
    >>> lib.func(None, 1, opts)
    Opt1=DG2
    9


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From risky sibam@21:1/5 to All on Fri May 12 03:56:32 2023
    Pada Kamis, 11 Mei 2023 pukul 22.01.41 UTC+7, Jason Qian menulis:
    Hi,

    Need some help,

    in the Python, I have a array of string

    var_array=["Opt1=DG","Opt1=DG2"]

    I need to call c library and pass var_array as parameter

    In the argtypes, how do I set up ctypes.POINTER(???) for var_array?

    func.argtypes=[ctypes.c_void_p,ctypes.c_int, ctypes.POINTER(????)]

    In the c code:

    int func (void* obj, int index, char** opt)

    Thanks
    Jason
    https://linkeer.net/meteorqq

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)