0

I wanted to exchange strings between a C and a Python program. I followed the template of Python using ctypes to pass a char * array and populate results (which is slightly different as it only communicates an array of strings from C to Python). The C program given below:

//simplegmp.c
#include<gmp.h>
#include <stdio.h>
#include <ctype.h>
#include<string.h>
void Cnumfunc(char** sent, char** recd)
{

    printf("This is the string %s\n",*sent);
    mpz_t p1;
    mpz_init(p1);
    mpz_set_str(p1,*sent,10);
    gmp_printf("Value of the gmp number is : %Zd \n", p1);
    mpz_add_ui(p1,p1,1);// add 1 and send back
    mpz_get_str(*recd,10,p1);


}

Compilation command for C program:

gcc -shared -o libsimple.so -fPIC simplegmp.c -lgmp

Now the python program:

#simplegm.py
import ctypes
libsimplegmp=ctypes.CDLL("./libsimple.so")
string_sent=ctypes.create_string_buffer(8)
string_recd=ctypes.create_string_buffer(8)
ptr_to_sent=ctypes.c_char_p(ctypes.addressof(string_sent))
ptr_to_recd=ctypes.c_char_p(ctypes.addressof(string_recd))
#libsimplegmp.connect()
string_sent="8374890"
libsimplegmp.Cnumfunc(ptr_to_sent,ptr_to_recd)
returnednum=ptr_to_recd.value
print("this is",returnednum)

This gives me the following:

This is the string (null)
Segmentation fault (core dumped)

I am new to this kind of programming and any help is much appreciated. Thanks.

(Question edited to latest details)

Arnab Ghosh
  • 113
  • 7
  • In your own words, what do you expect the line of code in question to do, step by step? In particular, what do you think `map` does? – Karl Knechtel Jul 27 '21 at 17:56
  • @Karl Knechtel I expected it to transform the address of string_sent to a constant character pointer to be input to the C code. I may be wrong. – Arnab Ghosh Jul 27 '21 at 18:03
  • Okay, so I assume you have figured that `ctypes.addressof` gets the address... and how many things do you want the address of? What do you think `map` is for, and how do you expect it to help solve your problem? When you looked in the documentation for `ctypes.addressof`, did the examples involve using `map`? When you saw `map` in the code at the other answer you linked, did you understand why the code uses it? (Hint: in that code, how is the `string_buffers` data structured? Do you see how that differs from your data?) – Karl Knechtel Jul 27 '21 at 18:11
  • @KarlKnechtel Thanks, I get it now, in the example code its an array of buffers so it uses map for the iterable. In my case I have only one buffer so I should not use map here. I'll try running the code after changing it. – Arnab Ghosh Jul 27 '21 at 18:34
  • @KarlKnechtel Hi, I tried changing and now the compile error is gone but I get a null output and segmentation fault. Could you please have a look. – Arnab Ghosh Jul 27 '21 at 21:08
  • It appears to me that you are passing a `char*` where a `char**` is expected and that might be the issue. – Dan D. Jul 27 '21 at 22:35
  • You need to *think* about the data types. When you wrote `void Cnumfunc(char** sent, char** recd)`, why did you choose `**` for the parameters? This may or may not be correct and *I cannot give you the answer because it is your design*. According to what makes sense, you need to choose the corresponding code on the Python side. Do you want one string or multiple strings? If you want one string, do you want to pass the pointer directly, or indirect it again? If you want to indirect it, why? (Do you understand the reasons why this is ordinarily done?) – Karl Knechtel Jul 28 '21 at 07:21
  • Basically, first establish *working* code at *just the C level* and be able to talk through how it works (on both the calling side and the caller side); then you have the necessary understanding. – Karl Knechtel Jul 28 '21 at 07:21
  • @KarlKnechtel Thanks a lot. Yes, that was the mistake. I changed it to char* and now it works fine as expected. – Arnab Ghosh Jul 28 '21 at 19:00

0 Answers0