3

I have a C api function with the following prototype which I wish to call from Python 2.6/2.7 via the ctypes module.

C function :

int function_name( char *outputbuffer, int outputBufferSize, 
                   const char *input, const char *somestring2 );

Here outputbuffer is a kind of string buffer in which a string is to be inserted as the output once this function is called on the basis of input and somestring2.

How do we create this buffer (output buffer) in python and what would be the argtype for this function

3
  • I'm not an expert in Python, but check ctypes and create_string_buffer. Commented Dec 8, 2020 at 9:21
  • Why did you add the c++ tag? The question clearly indicates that the topic of interest is a "C api function". Commented Dec 8, 2020 at 9:48
  • @pqans sorry for any kind of inconvenience caused . I guess the c++ tag was there in recommendations, so got added inadvertently. will delete it. Commented Dec 8, 2020 at 10:06

1 Answer 1

3

First, you import the ctypes module. Then you need to load your c dll containing the said function. After that you need to set the argument types and the result type of that function. Finally you create your destination buffer and call your function.

Python:

import ctypes as ct

MAX_BUFSIZE = 100
  
mycdll = ct.CDLL("path_to_your_c_dll")  # for windows you use ct.WinDLL(path)

mycdll.function_name.argtypes = [ct.c_char_p, ct.c_int,
                                 ct.c_char_p, ct.c_char_p]

mycdll.function_name.restype = ct.c_int

mystrbuf = ct.create_string_buffer(MAX_BUFSIZE)
result = mycdll.function_name(mystrbuf, len(mystrbuf), 
                              b"my_input", b"my_second_input")

Working example using strncpy:

import ctypes as ct

MAX_BUFSIZE = 100

mycdll = ct.CDLL("libc.so.6")  # on windows you use cdll.msvcrt, instead

mycdll.strncpy.argtypes = [ct.c_char_p, ct.c_char_p, ct.c_size_t]

mycdll.strncpy.restype = ct.c_char_p

mystrbuf = ct.create_string_buffer(MAX_BUFSIZE)
dest = mycdll.strncpy(mystrbuf, b"my_input", len(mystrbuf))

print(mystrbuf.value)

Python 3 output:

user@Mint20:~/Dokumente/Programmieren/sites/Stackoverflow$ python3 --version
Python 3.8.5

user@Mint20:~/Dokumente/Programmieren/sites/Stackoverflow$ python3 python_ctypes.py 
b'my_input'

Python 2 output:

user@Mint20:~/Dokumente/Programmieren/sites/Stackoverflow$ python2 --version
Python 2.7.18

user@Mint20:~/Dokumente/Programmieren/sites/Stackoverflow$ python2 python_ctypes.py 
my_input
Sign up to request clarification or add additional context in comments.

7 Comments

thanks for the answer. i am not getting the output stored/returned in the mystrbuf . Also, i tried sending the inputs both ways like you suggested as b"my_input" , and ct.c_char_p("my_input"). But mystrbuf is still empty. Any thoughts ?
Instead of loading your c code, load the libc.so.6 or the msvcrt if you are working on linux or windows respectively. Replace the function_name with strncpy and provide the correct arg- and restypes. Then you see that it works! How is your c code looking?
I just added an working example with the suggested strncpy
one more thing forgot to add , i am working on python 2. Is there any major change in ctypes for python 2 and 3 ?
See docs.python.org/2.7/library/ctypes.html, however i don't know the featureset of this early version.
|

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.