在 Visual C++ 中从 System::String 转换为 Char

本文介绍在 Visual C++ 中使用托管扩展从 System::String* 中转换到 char* 的几种方法。

原始产品版本: Visual C++
原始 KB 数: 311259

总结

本文介绍以下Microsoft .NET Framework 类库命名空间:

  • System::Runtime::InteropServices
  • Msclr::interop

本文讨论以下几种从中转换 System::String*char* 的方法:

  • Visual C++ .NET 2002 和 Visual C++ .NET 2003 中用于C++的托管扩展
  • Visual C++ 2005 和 Visual C++ 2008 中的 C++/CLI

方法 1

PtrToStringChars 提供指向实际 String 对象的内部指针。 如果将此指针传递给非托管函数调用,则必须首先固定指针以确保对象在异步垃圾回收过程中不会移动:

//#include <vcclr.h>
System::String * str = S"Hello world\n";
const __wchar_t __pin * str1 = PtrToStringChars(str);
wprintf(str1);

方法 2

StringToHGlobalAnsi 将托管 String 对象的内容复制到本机堆中,然后动态将其转换为美国国家标准研究所(ANSI)格式。 此方法分配所需的本机堆内存:

//using namespace System::Runtime::InteropServices;
System::String * str = S"Hello world\n";
char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
printf(str2);
Marshal::FreeHGlobal(str2);

注意

在 Visual C++ 2005 和 Visual C++ 2008 中,必须添加公共语言运行时支持编译器选项(/clr:oldSyntax)才能成功编译前面的代码示例。 若要添加公共语言运行时支持编译器选项,请执行以下步骤:

  1. 单击“项目,然后单击“ProjectName 属性”。

    注意

    ProjectName 是项目名称的占位符。

  2. 展开 配置属性,然后单击“ 常规”。

  3. 在右窗格中,单击以在公共语言运行时支持项目设置中选择公共语言运行时支持、旧语法(/clr:oldSyntax)。

  4. 单击“应用”,然后单击“确定”

有关公共语言运行时支持编译器选项的详细信息,请访问以下Microsoft开发人员网络(MSDN)网站:

/cgthreads(公共语言运行时编译)

这些步骤适用于整个文章。

方法 3

VC7 CString 类具有一个构造函数,该构造函数采用托管字符串指针并加载 CString 其内容:

//#include <atlstr.h>
System::String * str = S"Hello world\n";
CString str3(str);
printf(str3);

方法 4

Visual C++ 2008 引入了 marshal_as<T> 封送帮助类和 marshal_context() 封送帮助程序类。

//#include <msclr/marshal.h>
//using namespace msclr::interop;
marshal_context ^ context = gcnew marshal_context();
const char* str4 = context->marshal_as<const char*>(str);
puts(str4);
delete context;

注意

此代码不使用 Visual C++ .NET 2002 或 Visual C++ .NET 2003 中C++的托管扩展进行编译。 它使用 Visual C++ 2005 中引入的新 C++/CLI 语法和 2008 年 Visaul C++ 中引入的新 msclr 命名空间代码。 若要成功编译此代码,必须在 Visual C++ 2008 中使用 /clr C++ 编译器开关。

用于C++示例代码的托管扩展(Visual C++ 2002 或 Visual C++ 2003)

//compiler option: cl /clr
#include <vcclr.h>
#include <atlstr.h>
#include <stdio.h>
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;

int _tmain(void)
{
    System::String * str = S"Hello world\n";

    //method 1
    const __wchar_t __pin * str1 = PtrToStringChars(str);
    wprintf(str1);

    //method 2
    char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
    printf(str2);
    Marshal::FreeHGlobal(str2);

    //method 3
    CString str3(str);
    wprintf(str3);

    return 0;
}

C++/CLI 示例代码(Visual C++ 2005 和 Visual C++ 2008)

//compiler option: cl /clr

#include <atlstr.h>
#include <stdio.h>
#using <mscorlib.dll>

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

#if _MSC_VER > 1499 // Visual C++ 2008 only
#include <msclr/marshal.h>
using namespace msclr::interop;
#endif

int _tmain(void)
{
    System::String ^ str = "Hello world\n";

    //method 1
    pin_ptr<const wchar_t> str1 = PtrToStringChars(str);
    wprintf(str1);

    //method 2
    char* str2 = (char*)Marshal::StringToHGlobalAnsi(str).ToPointer();
    printf(str2);
    Marshal::FreeHGlobal((IntPtr)str2);

    //method 3
    CString str3(str);
    wprintf(str3);

    //method 4
    #if _MSC_VER > 1499 // Visual C++ 2008 only
    marshal_context ^ context = gcnew marshal_context();
    const char* str4 = context->marshal_as<const char*>(str);
    puts(str4);
    delete context;
    #endif

    return 0;
}