【发布时间】:2022-01-04 05:04:19
【问题描述】:
目前我有 C++ 加载 DLL。我需要用 python 替换 C++ 代码。我的问题是:
- 在回调函数 device_ID1_callback 中,所有值似乎都是空的,我猜我没有正确使用指针。
- 在调用 device_get_info 之后,所有的值都是 0,我想得到一些不为零的值。 几个星期以来,我尝试了任何我能想到的方法,但运气不佳。
为了简化问题,这里是我的部分代码。感谢您的时间和帮助!
在我的 lib.h 文件中,我有
typedef unsigned int DeviceHandler;
typedef struct {
unsigned int fpga_version;
}DeviceInfo_t;
typedef struct {
unsigned int check_id;
float distance[256];
}MeasureResult_t;
DLLEPXORT int EXCALL device_add(DeviceHandler* outHandler, char* device_ip, MeasureModeCallback callback);
DLLEPXORT void EXCALL device_get_info(DeviceHandler handler, DeviceInfo_t* p_device_info);
在示例 C++ 文件中: """
void device_ID1_callback(const void *out,unsigned int out_num){
MeasureResult_t *ptr = (MeasureResult_t *)out;
printf("[ChechID:0x%x] %d pack's data\n",ptr[0].check_id,out_num);
}
void demo_callback_mode(){
int ret;
DeviceHandler device_handler;
DeviceInfo_t device_info;
ret = device_add(&device_handler,"192.168.1.2",&device_ID1_callback);
device_get_info(device_handler,&device_info);
printf("[FPGA] version : %d\n", device_info.fpga_version);
}
""" *c++ 结束 *
这是我的 Python 代码: """
import ctypes as c
class MeasureResult_t(c.Structure):
_fields_ = [
('check_id', c.c_int),
('distance[256]', c.c_float)]
class DeviceInfo_t(c.Structure):
_fields_ = [
('fpga_version', c.c_int)
]
def device_ID1_callback(out, out_num):
print("---enter device call back function---")
print(dir(out))
print("out: ",out.contents)
#print(dir(out))
print("out_num:",out_num)
print("---exit device call back function---\n\n")
return 0
_dev = c.CDLL("./OPSensor/osp_lidar")
T_device_handler = c.c_int
T_device_handler_ptr = c.POINTER(T_device_handler)
_dev.device_add.argtypes = [T_device_handler_ptr, c.c_char_p]
_dev.device_add.restype = c.c_int
device_handler = c.c_int()
ip_val = c.c_char_p("192.168.1.2".encode('utf-8'))
out = MeasureResult_t()
out_num = c.c_int()
CMPFUNC_t = c.CFUNCTYPE(None, c.POINTER(MeasureResult_t), c.c_int)
MeasureModeCallback = CMPFUNC_t(device_ID1_callback)
ret = _dev.device_add(c.byref(device_handler), (ip_val), MeasureModeCallback(c.byref(out), out_num))
_dev.device_get_info.argtypes = [T_device_handler_ptr, c.POINTER(DeviceInfo_t)]
_dev.device_get_info.restype = c.c_void_p # assume it returns C int
p_device_info = DeviceInfo_t()
#_dev.device_get_info(c.byref(device_handler), c.byref(p_device_info)) # does not work
_dev.device_get_info((device_handler), c.byref(p_device_info)) #does not work either
print(device_handler) # I have correct device_handler value
print(p_device_info.fpga_version) # the value i got is 0, does seem right
"""
【问题讨论】:
-
关于 1. 您在代码中调用“MeasureModeCallback”,而您只能将其用作“device_add”的参数。
-
关于 2. 在 C++ 代码中调用“device_get_info”,其值为“device_handler”作为第一个参数,但在 Python 中使用指向“device_handler”(“byref”)的指针。
-
感谢您花时间看我的帖子。我可能是错的,但 MeasureModeCallback 是一个带有返回值和两个输入变量的 CFUNCTYPE 变量。 CMPFUNC_t = c.CFUNCTYPE(None, c.POINTER(MeasureResult_t), c.c_int) MeasureModeCallback = CMPFUNC_t(device_ID1_callback) 关于 2) 我尝试了很多不同的东西,这只是我尝试过的一个版本。它们都不适合我。
-
“MeasureModeCallback”是具有指定参数和输出类型的特定函数类型“CMPFUNC_t”的实例。这种函数类型的实例是一个函数,调用这个函数会产生一个返回值。
-
迈克尔,很明显我不知道我在说什么。你完全正确。再次感谢您的帮助。
标签: python c++ dll callback ctypes