我想在Python上使用C库。 然后,我想从C库功能获取消息(char *)。
我写了这些代码。 我得到了结果值(double * result_out),但没有收到消息。 此代码显示为“ c_char_p(None)”。
有什么想法吗?
我使用Python 3.6和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.
答案 0 :(得分:0)
这里的主要问题是您的C被破坏了。为msg
参数赋值不会在调用者端产生任何可见的效果(就像您试图在Python函数中为参数赋值一样)。
如果您想将错误消息字符串实际提供给div
的调用者,则需要使用char**
,而不是char*
,并分配给{{1} }。在Python端,您将传递类似*msg
的信息。
除此之外,您需要在byref(errmsg)
上设置argtypes
和restype
,否则Python将不知道如何正确传递参数。
答案 1 :(得分:0)
要返回一个值作为输出参数,您需要将一个指针传递给返回的值类型。就像您使用double*
来获得加倍一样,您也需要char**
来获得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;
}
在Python中,您还需要声明参数类型,否则Python默认将c_int
的值编组到C,这将破坏double
并可能破坏char*
取决于操作系统的指针实现:
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)
输出:
b'0 div error'