I want to use C library on Python. Then, I want to get message ( char* ) from C library fanction.
I wrote these codes. I got result value(double* result_out) , but I didn't get message. This code shown "c_char_p(None)".
Any ideas?
I use Python 3.6, and Ubuntu Bash.
C (libdiv.so):
#define ERROR -1
#define OK 0
int div (double x, double y, char *msg, double *result_out) {
static char *err_msg = "0 div error";
if(y == 0) {
msg = err_msg;
return ERROR;
}
*result_out = x/y;
return OK;
}
Python:
from ctypes import *
lib = cdll.Loadlibrary('libdiv.so')
errmsg = c_char_p()
result = c_double(0)
rtn = lib.div(10, 0, errmsg, byref(result))
if rtn < 0:
print (errmsg) # None
else :
print (result.value) # OK.
The primary problem here is that your C is busted. Assigning a value to the msg
argument doesn't do anything visible on the caller's end (just like if you'd tried to assign to an argument in a Python function).
If you want to actually make the error message string available to the caller of div
, you need to take a char**
, not a char*
, and assign to *msg
. On the Python end, you'd pass something like byref(errmsg)
.
Aside from that, you need to set the argtypes
and restype
on lib.div
, or Python won't know how to pass arguments correctly.
To return a value as an output parameter, you need to pass a pointer to the value type returned. Just like you used double*
to receive a double, you need a char**
to receive a char*
:
#ifdef _WIN32
# define API __declspec(dllexport)
#else
# define API
#endif
#define OK 0
#define ERROR -1
API int div(double x, double y, char** ppMsg, double* pOut)
{
static char* err_msg = "0 div error";
if(y == 0)
{
*ppMsg = err_msg;
return ERROR;
}
*pOut = x / y;
return OK;
}
In Python, you'll also need to declare the argument types, or Python will marshal the values to C as c_int
by default, which will break double
and may break char*
depending on the pointer implementation of your OS:
from ctypes import *
lib = CDLL('test')
lib.div.argtypes = c_double,c_double,POINTER(c_char_p),POINTER(c_double)
lib.div.restype = c_int
errmsg = c_char_p()
result = c_double()
rtn = lib.div(10, 0, byref(errmsg), byref(result))
if rtn < 0:
print(errmsg.value)
else:
print(result.value)
Output:
b'0 div error'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.