首页 > 解决方案 > C DLL (unitybridge.dll) 对 Python 函数的异步回调

问题描述

我正在基于 Golang 中的代码在 Python 中重新设计 DJI Robomaster S1 应用程序(https://git.bug-br.org.br/bga/robomasters1/src/master/app/internal/dji/unity/bridge/包装)。在这段代码中,他们使用了一个与机器人进行大部分通信的 unitybridge.dll。与此 dll 的通信主要通过(异步)回调进行。我使用 ctypes 来访问 C 中的代码。
我使用了一个 C 库“libffcall”,它返回一个指向回调的指针(也在 Go 中使用)。由于代码非常复杂,我将在这里做一个小例子,它应该可以工作,但不能。通常这应该创建、初始化网桥并启动连接(通过发送特定事件)。这些似乎都有效。当桥中发生特定事件(由我选择,因为它每隔几秒钟发生一次)时设置回调时,没有任何反应。\

alloc_helper.c:使用 libffcall 进行回调。为了使事情尽可能简单,回调只打印一些东西:

#include <stdio.h>
#include "alloc_helper.h"
#include "event_callback_windows.h"
#include <stdlib.h>

callback_t alloc_callback_python(void* data) {
   
    return alloc_callback(&event_callback, data);
}

event_callback_windows.c:应该由 unitybridge.dll 调用,最终会调用 python 函数(本例中没有做)

void event_callback(void* context, va_alist alist) {
    prinf("This should print");
}

example.py:参数中的值与 Go 中的相同

from ctypes import *
import time

# load the C-code
dll = CDLL("./unitybridge.dll")
alloc_helper = CDLL("./alloc_helper.so")

# create bridge args: str name, bool debuggable
dll.CreateUnityBridge(c_char_p(b"Robomaster", c_int(1))

# init bridge (returns True if successfull)
b = dll.UnityBridgeInitialize()
print("BOOL after init: {}".format(b))

# send event that starts connection
# args: event_code, data, sub_type
dll.UnitySendEvent(c_unint64(100 << 32), None, 0)

# set returntype
alloc_helper.alloc_callback_python.restype = POINTER(c_int)

# make callback
cb = alloc_helper.alloc_callback_python(None) # None to make is as simple as possible

# set event callback
# args: event_code (when this events occurs: call cb), callback
dll.UnitySetEventCallback(c_uint(304 << 32), cb)

time.sleep(3) # to give the bridge some time to make callbacks

# uninit and destroy bridge
dll.UnityBridgeUninitialze() # typo is not a mistake -> defined that way in dll
dll.DestroyUnityBridge()
time.sleep(5)

这是我的第一篇文章,所以请随时询问更多信息,因为我可能忘记了一些。我尝试了(几乎)一切,真的很想解决这个问题。

提前感谢<3

标签: pythoncunity3ddllctypes

解决方案


推荐阅读