Calling C functions on Python prints only the first character

Viewed 178

I tried to call c function in python here is my code

string.c

#include <stdio.h>

int print(const char *str)
{
  printf("%s", str):
  return 0;
}

string.py

from ctypes import *
so_print = "/home/ubuntu/string.so"
my_functions = CDLL(so_print)
print(my_functions.print("hello"))

when i run the python script it prints only the fist character of the string example "h"

How can i pass any string and my c code will read and display it.

2 Answers

Your function accepts a const char*, which corresponds to a Python bytes object (which coerces to c_char_p), not a str (which coerces to c_wchar_p). You didn't tell Python what the underlying C function's prototype was, so it just converted your str to a c_wchar_p, and UTF-16 or UTF-32 encoded string with solely ASCII characters looks like either an empty or single character (depending on platform endianness) C-style char * string.

Two things to improve:

  1. Define the prototype for print so Python can warn you when you misuse it, adding:

    my_functions.print.argtypes = [c_char_p]
    

    before using the function.

  2. Encode str arguments to bytes so they can be converted to valid C-style char* strings:

    # For arbitrary string, just encode:
    print(my_functions.print(mystr.encode()))
    
    # For a literal, you can pass a bytes literal
    print(my_functions.print(b"hello"))
                           # ^ b makes it a bytes, not str
    

You have to make the following change here.

  • Pass byteobject instead of string.

This because of as per the Fundamental data types c_char_p in c is python 's byte object equivalent type

from ctypes import *
so_print = "string.so"
my_functions = CDLL(so_print)
print(my_functions.print(b"hello"))
Related