作为 C 回调的异步 python 函数

问题描述 投票:0回答:1

我所处的情况是,我需要使用一个 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
}
python c python-asyncio ctypes
1个回答
0
投票

经过一番搜索,我相信

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
的论点。

© www.soinside.com 2019 - 2024. All rights reserved.