簡體   English   中英

如何將帶有 null 字符的字符串從 C++ DLL 返回到 ZA7F5F35426B927411FC9231B56

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM