使用char缓冲区从DLL创建C函数的python回调。

时间:2018-04-25 00:04:06

标签: python c ctype

我正在尝试为C DLL创建一个python包装器。 C DLL使用回调来发送"发送"来自DLL的UDP消息。

我期望发生的是python代码将加载DLL库和两个函数。然后它将使用RegisterCallbackSendMessage函数向DLL注册回调。指向回调的指针将存储在DLL存储空间的内存中。然后python代码将调用SendWhoIs DLL函数。此函数将创建一个缓冲区并使用SendMessage函数指针将消息从DLL发送到python代码。

我遇到的问题是python中message函数中的SendMessage参数不知道如何解释void *而我无法将此缓冲区传递给sock.sendto功能。

我收到以下错误。

sock.sendto(message, (UDP_IP, UDP_PORT))
TypeError: a bytes-like object is required, not 'int'

我的问题是:如何将c_void_p转换为sock.sendto可以接受的字节数组。

我尽可能地减少了我的代码,但仍然可以理解。

这是我的C代码

// C DLL code 
// 

#define DllExport extern "C" __declspec( dllexport )

typedef uint16_t(*FPCallbackSendMessage)(const uint8_t * message, const uint32_t length);
FPCallbackSendMessage g_CallbackSendMessage;

DllExport bool RegisterCallbackSendMessage(uint16_t(*p_CallbackSendMessage)(const uint8_t * message, const uint32_t length)) {
    g_CallbackSendMessage = p_CallbackSendMessage ; 
    return true;
}

void SendWhoIs(unsigned int dd) {
    printf("dd=%d", dd); 
    char buffer[500];
    g_CallbackSendMessage( buffer, 500 ); 
}

这是我的python代码

# Python code 
# =================
print("Start") 

customDLL = cdll.LoadLibrary ("customeDLL.dll")

def SendMessage( message, length ):
    print("SendMessage...") 
    UDP_IP = "192.168.1.1"
    UDP_PORT = 47808
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.sendto(message, (UDP_IP, UDP_PORT))
    return True 

print("Registering Callback SendMessage...") 
SendMessageFUNC = CFUNCTYPE(c_bool, c_void_p, c_uint)
SendMessage_func = SendMessageFUNC( SendMessage )

RegisterCallbackSendMessage = customDLL.RegisterCallbackSendMessage
RegisterCallbackSendMessage.argtypes = [ SendMessageFUNC ]
RegisterCallbackSendMessage( SendMessage_func ) 

print("Do message...") 
SendWhoIs = BACnetStackDLL.SendWhoIs
SendWhoIs.argtypes = [c_uint]

SendWhoIs( 47 )

print("End") 

1 个答案:

答案 0 :(得分:1)

我明白了。

在python SendMessage函数中的

我想出了一种将c_void_p转换为字节数组的方法。

Target