我所处的情况是,我需要使用一个 C 库来调用 python 函数来实现 IO 目的,因此我不必为 IO 创建一个等效的 C 库。 python 代码库大量使用了
asyncio
并且所有 IO 都经过队列。 C 代码使用 ctypes
作为 dll 加载。问题是您无法从 C 回调中 await
。 有没有办法使用异步 python 函数作为 C 回调?
下面是它的工作原理。 我唯一的选择是做类似
non_async_callback
的事情,还是有什么办法可以使用 ctypes 等待 C 的到来。
蟒蛇
import asyncio
import time
import ctypes
DLL_PATH="./bin/test.dll"
dll = ctypes.CDLL(DLL_PATH)
incoming_queue=asyncio.Queue()
outgoing_queue=asyncio.Queue()
c_func = ctypes.CFUNCTYPE(ctypes.c_uint8, ctypes.c_uint8)
async def python_callback(test_num):
await outgoing_queue.put(test_num)
test_num = await incoming_queue.get()
return test_num
def non_async_callback(test_num):
while True:
try:
outgoing_queue.put_nowait(test_num)
break
except asyncio.QueueFull:
time.sleep(0.1)
continue
while True:
try:
test_num = incoming_queue.get_nowait(test_num)
break
except asyncio.QueueFull:
time.sleep(0.1)
continue
return test_num
# Called at some point during initialization
def setup_callback():
dll.setup_callback(c_func(python_callback))
C
uint8_t (CALLBACK*)(uint8_t);
CALLBACK py_callback
void setup_callbacks(void* callback)
{
py_callback = callback;
}
// Called from somewhere else in the C code.
uint8_t python_callback(uint8_t value)
{
uint8_t result = py_callback(value);
// Do something with result
}
经过一番搜索,我相信
async def python_callback(test_num):
await outgoing_queue.put(test_num)
test_num = await incoming_queue.get()
return test_num
可以用类似的东西包裹
def non_async_callback(test_num):
loop = asyncio.new_event_loop()
test_num = loop.run_until_complete(python_callback)
return test_num
我不确定传递给
run_until_complete
的论点。