Calling argc/argv function with ctypes

Question:

I am creating a wrapper to a code in c for Python. The c code basically runs in terminal and has the following main function prototype:

void main(int argc, char *argv[]){
f=fopen(argv[1],"r");
f2=fopen(argv[2],"r");

So basically arguments read are strings in terminal. I created following python ctype wrapper, but it appears I am using wrong type. I know the arguments passed from the terminal is read as characters but an equivalent python side wrapper is giving following error:

import ctypes
_test=ctypes.CDLL('test.so')

def ctypes_test(a,b):
  _test.main(ctypes.c_char(a),ctypes.c_char(b))

ctypes_test("323","as21")



TypeError: one character string expected

I have tried adding one character, just to check if shared object gets executed, it does as print commands work but momentarily till the section of the code in shared object needs file name. I also tried
ctypes.c_char_p but get.

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Updated as per the suggestion in the comments to the following:

def ctypes_test(a,b):
      _test.main(ctypes.c_int(a),ctypes.c_char_p(b))
ctypes_test(2, "323 as21")

Yet getting the same error.

Asked By: gfdsal

||

Answers:

Using this test DLL for Windows:

#include <stdio.h>

__declspec(dllexport)
void main(int argc, char* argv[])
{
    for(int i = 0; i < argc; ++i)
        printf("%sn", argv[i]);
}

This code will call it. argv is basically a char** in C, so the ctypes type is POINTER(c_char_p). You also have to pass bytes strings and it can’t be a Python list. It has to be an array of ctypes pointers.

>>> from ctypes import *
>>> dll = CDLL('./test')
>>> dll.main.restype = None
>>> dll.main.argtypes = c_int, POINTER(c_char_p)
>>> args = (c_char_p * 3)(b'abc', b'def', b'ghi')
>>> dll.main(len(args), args)
abc
def
ghi
Answered By: Mark Tolonen
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.