On Mon, Jun 6, 2016 at 9:50 AM, Mark Summerfield <l...@qtrac.plus.com> wrote: > > Lib = ctypes.cdll.LoadLibrary("libthing")
Use ctypes.CDLL('libthing'). It's simpler, plus it's the only way to pass the handle, mode, and use_errno parameters if you need them. > LibOpen.restype = ctypes.c_int This line isn't required because c_int is the default result type. > argc = ctypes.c_int(len(sys.argv)) ctypes automatically converts integer arguments that are passed by value. You only need to create a c_int when you're passing by reference. > Args = ctypes.c_char_p * len(sys.argv) The argv array in ANSI C should have length `argc + 1`. There's a final null terminator, even though it's redundant given the argc count. > args = Args(*[ctypes.c_char_p(arg.encode("utf-8")) > for arg in sys.argv]) There's no need to create a list just to unpack it. You can use a for loop to populate the array directly. Also, you don't have to manually instantiate c_char_p instances when storing the elements of a c_char_p array; the base type's getfunc will convert Python byte strings. Also, since the function signature isn't `const char **`, you should use ctypes.create_string_buffer just in case the function expects to be able to modify the argv strings. This requires switching from using c_char_p to a more generic POINTER(c_char). > argv = ctypes.pointer(args) > LibOpen(argc, ctypes.byref(argv)) C array arguments are passed as a pointer to the first element. You don't have to manually create a pointer. And if you do, certainly you shouldn't pass it by reference. That mistakenly passes a pointer to the pointer to the first element of the argv array (which is a pointer to the first character in the first string argument). Naturally you get the following error: > expected LP_c_char_p instance instead of pointer to LP_c_char_p_Array_1 Due to limitations in ctypes you also get the following error when you pass the pointer by value: > expected LP_c_char_p instance instead of LP_c_char_p_Array_1 Only passing the array directly is special cased for this to work. Try the following code: import sys import ctypes lib = ctypes.CDLL('libthing') LP_c_char = ctypes.POINTER(ctypes.c_char) LP_LP_c_char = ctypes.POINTER(LP_c_char) lib.LibOpen.argtypes = (ctypes.c_int, # argc LP_LP_c_char) # argv argc = len(sys.argv) argv = (LP_c_char * (argc + 1))() for i, arg in enumerate(sys.argv): enc_arg = arg.encode('utf-8') argv[i] = ctypes.create_string_buffer(enc_arg) lib.LibOpen(argc, argv) -- https://mail.python.org/mailman/listinfo/python-list