[英]How to return a string with null characters from C++ DLL to Python?
我正在開發一個 Python 3 應用程序,該應用程序調用在 C++ 中開發的 DLL。 DLL 讀取數據庫記錄並將記錄緩沖區返回給 Python 應用程序。 我遇到的問題是數據庫記錄可能包含 x'00'(空)字符。 發生這種情況時,返回到 Python 應用程序的記錄緩沖區在 null 字符處被截斷。
我正在使用memcpy將記錄緩沖區復制到 Python 返回區域。 我認為 memcpy 復制了指定的字節數,而不管內容如何。
我不是 C++ 程序員,所以我很可能會誤解 memcpy 的工作原理。
以下代碼片段是測試代碼示例,將演示我遇到的問題。
這是 DLL:
#include "pch.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define LIBDLL extern "C" __declspec(dllexport)
LIBDLL int readData_VPRI2(char* buffer, unsigned long buffer_length )
{
char unsigned buf[20];
int unsigned buf_len;
FILE* stream;
errno_t err;
err = fopen_s(&stream, "D:\\testfile", "rb");
if (err != 0) return err;
fread(buf, buffer_length, 1, stream);
memcpy(buffer, buf, buffer_length);
return 0;
}
這是 Python 調用例程:
import ctypes
from ctypes import *
dll = ctypes.CDLL('C:\\Users\\rhkea\\source\\repos\\TestDLL\\x64\\Debug\\TestDLL.dll')
f = open("D:\\testfile", "wb")
test_string = bytes('ABCD\x00efg', encoding='utf-8')
f.write(test_string)
f.close()
char_arr = ctypes.c_char * 500 # set up the return area
buffer = char_arr() # assign the buffer
readData_VPRI2 = dll.readData_VPRI2 # get the DLL
readData_VPRI2.restype = ctypes.c_int # set the return type
readData_VPRI2.argtypes = (POINTER(c_char), c_long) # define the arguments
rc = readData_VPRI2(buffer, len(test_string)) # call the DLL
print ("rc =", rc)
if rc==0:
print ("buffer =", buffer.value)
print ("buffer length = ", len(buffer.value))
Python執行的output為:
rc = 0
buffer = b'ABCD'
buffer length = 4
如圖所示,返回的緩沖區在 x'00' 處被截斷。
我猜可能有一些我忽略或不理解的簡單事情。 任何有關如何糾正此問題的指導將不勝感激。
提前致謝。
事實證明,C++ 代碼按設計工作。 我關於memcpy
的問題不是問題。 它按記錄工作。
我發現 Python 實際上可能正在截斷字符串。 cytpes.c_char.value
返回截斷的字符串,如我原來的問題中所述。
但是,如果您使用cyptes.c_char.raw
則返回整個字符串(在我的示例中為buffer
)(例如,500 字節),並用 x'00' 填充。 所以print(buffer.raw)
返回:
b'AB\x00CDefg\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00... ...\x00'
由於我已經知道我期望返回的記錄的長度,我可以簡單地從buffer.raw
中分割它。
感謝您的回復。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.