.NET System::String 到存储在 char* 中的 UTF8 字节

0

本文介绍了.NET System::String 到存储在 char* 中的 UTF8 字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我在 .NET 项目中封装了一些非托管 C++ 代码.为此,我需要将 System::String 转换为存储在 char* 中的 UTF8 字节.

I am wrapping some unmanaged C++ code inside a .NET project. For this I need to convert System::String to UTF8-bytes stored in char*.

我不确定这是否是最好的甚至是正确的方法,如果有人可以查看并提供反馈,我将不胜感激.

I am unsure if this is the best or even a correct way to do this and I'd appreciate if someone could take a look and provide feedback.

谢谢,

/大卫

// Copy into blank VisualStudio C++/CLR command line solution.
#include "stdafx.h"
#include <stdio.h>

using namespace System;
using namespace System::Text;
using namespace System::Runtime::InteropServices;

// Test for calling with char* argument.
void MyTest(const char* buffer)
{
    printf_s("%s
", buffer);
    return;
}

int main()
{

   // Create a UTF-8 encoding.
   UTF8Encoding^ utf8 = gcnew UTF8Encoding;

   // A Unicode string with two characters outside an 8-bit code range.
   String^ unicodeString = L"This unicode string contains two characters with codes outside an 8-bit code range, Pi (u03a0) and Sigma (u03a3).";
   Console::WriteLine(unicodeString);

   // Encode the string.
   array<Byte>^encodedBytes = utf8->GetBytes(unicodeString);

   // Get pointer to unmanaged char array
   int size = Marshal::SizeOf(encodedBytes[0]) * encodedBytes->Length;
   IntPtr pnt = Marshal::AllocHGlobal(size);
   Marshal::Copy(encodedBytes, 0, pnt, encodedBytes->Length);

   // Ugly, but necessary?
   char *charPnt= (char *)pnt.ToPointer();
   MyTest(charPnt);
   Marshal::FreeHGlobal(pnt);

}

推荐答案

  1. 无需创建编码器实例,使用静态实例即可.

  1. You don't need to create an encoder instance, you can use the static instances.

如果被调用的函数不期望指向 HGlobal 堆的指针,您可以对缓冲区使用普通的 C/C++ 内存分配(new 或 malloc).

If the called function doesn't expect a pointer to the HGlobal heap you can just use plain C/C++ memory allocation (new or malloc) for the buffer.

在您的示例中,该函数不具有所有权,因此您根本不需要副本,只需固定缓冲区即可.

In your example the function doesn't take ownership so you don't need a copy at all, just pin the buffer.

类似:

// Encode the text as UTF8
array<Byte>^ encodedBytes = Encoding::UTF8->GetBytes(unicodeString);

// prevent GC moving the bytes around while this variable is on the stack
pin_ptr<Byte> pinnedBytes = &encodedBytes[0];

// Call the function, typecast from byte* -> char* is required
MyTest(reinterpret_cast<char*>(pinnedBytes), encodedBytes->Length);

或者,如果您需要像大多数 C 函数(包括 OP 中的示例)一样以零结尾的字符串,那么您可能应该添加一个零字节.

Or if you need the string zero-terminated like most C functions (including the example in the OP) then you should probably add a zero byte.

// Encode the text as UTF8, making sure the array is zero terminated
array<Byte>^ encodedBytes = Encoding::UTF8->GetBytes(unicodeString + "");

// prevent GC moving the bytes around while this variable is on the stack
pin_ptr<Byte> pinnedBytes = &encodedBytes[0];

// Call the function, typecast from byte* -> char* is required
MyTest(reinterpret_cast<char*>(pinnedBytes));

这篇关于.NET System::String 到存储在 char* 中的 UTF8 字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

C# 中的多播委托奇怪行为?
Multicast delegate weird behavior in C#?(C# 中的多播委托奇怪行为?)...
2023-11-11 C#/.NET开发问题
6

如何将代表存储在列表中
How to store delegates in a List(如何将代表存储在列表中)...
2023-11-11 C#/.NET开发问题
6

Delegate.CreateDelegate() 和泛型:错误绑定到目标方法
Delegate.CreateDelegate() and generics: Error binding to target method(Delegate.CreateDelegate() 和泛型:错误绑定到目标方法)...
2023-11-11 C#/.NET开发问题
14

具有未知类型的 CreateDelegate
CreateDelegate with unknown types(具有未知类型的 CreateDelegate)...
2023-11-11 C#/.NET开发问题
5

将运算符与其他参数一起传递
Passing an operator along with other parameters(将运算符与其他参数一起传递)...
2023-11-11 C#/.NET开发问题
6

Func&lt;T&gt;.BeginInvoke 使用线程池吗?
Does Funclt;Tgt;.BeginInvoke use the ThreadPool?(Funclt;Tgt;.BeginInvoke 使用线程池吗?)...
2023-11-11 C#/.NET开发问题
6