Создание обратного вызова Python для функции C из DLL с буфером символов. - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь создать оболочку Python для C DLL. C DLL использует обратные вызовы для «отправки» сообщений через UDP из DLL.

Я ожидал, что код Python загрузит библиотеку DLL и две функции. Затем он регистрирует обратный вызов в DLL, используя функцию RegisterCallbackSendMessage. Указатель на обратный вызов будет храниться в памяти в пространстве памяти DLL. Затем код Python будет вызывать функцию DLL SendWhoIs. Эта функция создаст буфер и использует указатель функции SendMessage для отправки сообщения из DLL в код Python.

У меня проблема в том, что параметр message в функции SendMessage в python не знает, как интерпретировать 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 голосов
/ 26 апреля 2018

Я понял это.

в функции Python SendMessage я нашел способ конвертировать c_void_p в байтовый массив.

# convert the pointer to a buffer. 
buffer = c_char * length 
messageToSend = buffer.from_address(message)
...