使用 Dllimport 将一个非常大的字符串作为字节数组从 C++ 传递到 C#

Posted

技术标签:

【中文标题】使用 Dllimport 将一个非常大的字符串作为字节数组从 C++ 传递到 C#【英文标题】:passing a very large string as byte array from C++ to C# with Dllimport 【发布时间】:2018-09-20 22:17:42 【问题描述】:

我的 c++ dll 文件中有一个非常大的字符串,我需要将它作为字节数组传递给 C#,但我不知道该怎么做!

我知道我可以在 C# 中使用这个函数:

字符串结果 = System.Text.Encoding.UTF8.GetString(bytearray);

我的大字符串是 C++ 中的 std::string

我需要知道如何将我的字符串转换为 A utf8 数组并将其发送到 C# 以及如何在 C# 应用程序中取回字符串:)

有关问题的更多信息:

我不知道如何将字节数组从 C++ 解析为 C#,例如 swprintf 到 StringBuilder。

这是我的问题的示例代码:

C++ 代码:

#include "stdafx.h"
#include <iostream>
#include <cstdio>
#include <fstream>

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )

    switch (ul_reason_for_call)
    
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    
    return TRUE;



extern "C" __declspec(dllexport) void __stdcall sendasbyte(char* byte_to_send)

    std::ifstream file_t("testfile.txt");
    std::string Read_test_file((std::istreambuf_iterator<char>(file_t)),
                 std::istreambuf_iterator<char>());

    ///// NEED TO SEND Read_test_file as byte array to C# HERE :
    // <-------- CODE AREA --------->

这是 C# 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace minimal_project_testapp

    class Program
    
        [DllImport("minimal_project_test.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
        private static extern void sendasbyte(byte[] get_String_Byte);
        private static byte[] data_from_cpp;


        static void Main(string[] args)
        
            sendasbyte(data_from_cpp);
            string result = System.Text.Encoding.UTF8.GetString(data_from_cpp);
            Console.WriteLine(result);
            Console.ReadLine();
        
    

还有 testfile.txt:https://textuploader.com/dvvbb

【问题讨论】:

检查 C++ 中的字节是否正确地将文本编码为 UTF-8。 您正在发送 8 位文本并将其解释为 UTF16。你不会通过反复试验来解决问题。需要一些理解。从您可以在此处分享的最简单的测试程序开始。 @Cheersandhth.-Alf 抱歉,我不知道如何以及如何将其转换为 C#,如字符串生成器 :) 我编辑了问题 @DavidHeffernan 现在任何分钟... 您的 C++ 代码泄露,您发布的内容不完整。该错误可能在您未显示的代码中。 minimal reproducible example。不要为此到处乱扔文件。简化。让它最小化。那是调试 101。 【参考方案1】:

以下是如何做到这一点清晰而完美:D

1 > 将您的 c++ 函数 更改为:

extern "C" __declspec(dllexport) char* __stdcall test_int()

    std::ifstream file_t("testfile.txt");
    std::string Read_test_file((std::istreambuf_iterator<char>(file_t)),
    std::istreambuf_iterator<char>());
    int size_of_st = Read_test_file.length(); 
    std::string test1 = std::to_string(size_of_st);
    char* cstr = new char [size_of_st];
    std::strcpy(cstr, Read_test_file.c_str());
    return cstr; 

2 > 别忘了添加#define _CRT_SECURE_NO_WARNINGS

3 > 将 Dllimport 添加到您的 C# 应用程序

[DllImport("minimal_project_test.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern IntPtr test_int();

4> 最后像这样在任何需要的地方使用它:

        IntPtr _test_from_Cpp = test_int();
        int _test_char_count = <Enter Length of your string>;
        byte[] _out_char_value = new byte[_test_char_count];
        Marshal.Copy(_test_from_Cpp, _out_char_value, 0, _test_char_count);
        string final_string = System.Text.Encoding.UTF8.GetString(_out_char_value);

轰隆隆!有用 !!! ;)

【讨论】:

泄漏。不包括空终止符,因此无法确定长度。在非托管代码中进行不必要的复制。总而言之,不好。

以上是关于使用 Dllimport 将一个非常大的字符串作为字节数组从 C++ 传递到 C#的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 DLLImport 将字符串从 C# 传递到 C++(以及从 C++ 到 C#)?

Dllimport 将字符串从 C# 传递到 C++

有没有办法在 nginx 上使用 django 上传一个非常大的文件?

在 java 中解析非常大的 XML 文档(以及更多)

时间:2019-04-01 标签:c#dllimport parameters shift

将非常大的数字转换为十六进制字符串