0

I have a method define in C/C++ DLL that takes 2 args

void SetLines(char** args,int argCount);

I need to call it from Python, what is the proper way to do so.

from ctypes import *
path="test.dll"
lib = cdll.LoadLibrary(path)
Lines=["line 2","line 2"]
lib.SetLines(Lines,len(lines))
print(code)

Excuting the Python code gives the following error:

Traceback (most recent call last):
  File "<test.py>", line 6, in <module>
ctypes.ArgumentError: argument 1: <class 'TypeError'>: Don't know how to convert parameter 1
2
  • if figure it out.. using ctypes.Array(c_char_p,len)#len integer value, charpp =ctypes.Array(c_char_p,len)--> charpp[i]=c_char_p(Lines[i].encode("utf-8")) Commented May 21, 2015 at 6:22
  • indeed you have to use ctypes conversion for the list of strings. If you find the Answer, you could write it so new comers can find it Commented May 21, 2015 at 7:07

1 Answer 1

1

After some code digging I figure it out:

any C/C++ parameter that accepts a pointer to a list of values should be wrapped in python with

MyType=ctypes.ARRAY(/*any ctype*/,len)
MyList=MyType()

and filled with

MyList[index]=/*that ctype*/

in mycase the solution was:

from ctypes import *
path="test.dll"
lib = cdll.LoadLibrary(path)

Lines=["line 1","line 2"]
string_pointer= ARRAY(c_char_p,len(Lines)) 
c_Lines=string_pointer()
for i in range(len(Lines)):
    c_Lines[i]=c_char_p(Lines[i].encode("utf-8"))

lib.SetLines(c_Lines,len(lines))
Sign up to request clarification or add additional context in comments.

4 Comments

Lines[i].encode("<any encoding name>") is neccary because c_char_p accepts bytes not str (as I tested under Python 3.4.3)
ARRAY is deprecated. Create array types using the * operator. For example: c_lines = (c_char_p * len(Lines))(*(s.encode("utf-8") for s in Lines)).
both ways leads to the same result printing c_lines in both ways gives <code.c_char_p_Array_2 object at 0x0267F670> <code.c_char_p_Array_2 object at 0x0267F620>
ARRAY is kept around for backward compatibility with very old code. It's currently defined as just def ARRAY(typ, len): return typ * len. It's not documented and not even mentioned in the docs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.