How to pass const char* from python to c function

寵の児 提交于 2020-03-19 05:32:11

问题


I am using ctypes in Python to open a file for writing in C++.

My C++ code:

extern "C" {
void openfile(const char *filename) {
    cout<<"File to open for writing = " <<filename<<endl;
    FILE *fp = fopen(filename,"w");
    fprintf(fp,"writing into file");
    fclose(fp);
}
}

My Python code:

>>> import ctypes
>>> lib = ctypes.cdll.LoadLibrary('/in/vrtime/mahesh/blue/rnd/software/test/test.so')
>>> outfile = "myfirstfile.txt"
>>> lib.openfile(outfile)
File to open for writing = m

I am getting the file name as m, which is the first char charater of my file.

How to pass whole string to the C side?


回答1:


In python3 (and you are definitely using python3 as on python2 your code would luckily work) strings are stored as wchar_t[] buffers, so when you pass "myfirstfile.txt" the C function sees its arg as "m\0y\0..." which is obviously a C string of lenght one. Here is the problem manifested:

In [19]: from ctypes import cdll, c_char_p

In [20]: libc = cdll.LoadLibrary("libc.so.6")

In [21]: puts = libc.puts

In [22]: puts('abc')
a

You should pass to the C function a bytes object

In [23]: puts(b'abc')
abc

You can convert str to bytes like this:

puts(my_var.encode())

To avoid further confusion you may specify the argument types of C function:

In [27]: puts.argtypes = [c_char_p]

Now the function accepts bytes (ctypes converts it to char*):

In [28]: puts(b'abc')
abc

but not str:

In [30]: puts('abc')
---------------------------------------------------------------------------
ArgumentError                             Traceback (most recent call last)
<ipython-input-26-aaa5b59630e2> in <module>()
----> 1 puts('abc')

ArgumentError: argument 1: <class 'TypeError'>: wrong type


来源:https://stackoverflow.com/questions/37966432/how-to-pass-const-char-from-python-to-c-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!