将System::String转换为Const Char *

6
我正在使用Visual C++ 2008的GUI创建器制作用户界面。当单击按钮时,会调用以下函数。此内容应该创建一个文件,并以文本框“Textbox”中的内容命名文件并在末尾添加“.txt”。然而,这导致我遇到了转换错误。以下是代码: private: System::Void Button_Click(System::Object^ sender, System::EventArgs^ e) { ofstream myfile (Textbox->Text + ".txt"); myfile.close(); }
以下是错误信息:
error C2664:'std :: basic_ofstream <_ Elem,_ Traits> :: basic_ofstream(const char *,std :: ios_base :: openmode,int)':无法将参数1从'System :: String ^'转换为'const char *'
如何进行转换以使其通过?

哎呀,我好几年前写过这个,现在想不起来用什么编程语言写的了! - leppie
6个回答

9

很简单!

由于您使用的是托管C ++,因此请使用include并像这样操作:

#include <msclr/marshal.h>

...

void someFunction(System::String^ oParameter)
{
   msclr::interop::marshal_context oMarshalContext;

   const char* pParameter = oMarshalContext.marshal_as<const char*>(oParameter);

   // the memory pointed to by pParameter will no longer be valid when oMarshalContext goes out of scope
}

8
我会使用编组(marshalling)技术:
//using namespace System::Runtime::InteropServices;
const char* str = (const char*)(void*)
       Marshal::StringToHGlobalAnsi(Textbox->Text);
// use str here for the ofstream filename
Marshal::FreeHGlobal(str);

但需要注意的是,你只能使用 Ansi 字符串。如果需要 Unicode 支持,则可以使用 widechar STL 类 wofstreamPtrToStringChars (#include <vcclr.h>) 将其从 System::String 转换。在这种情况下,您无需释放 pinned 指针。


太棒了,那就是我写的代码!+1 - leppie
1
+1 我写的正是这个,只不过我更喜欢使用 static_cast<const char*>(Marshal::StringToHGlobalAnsi(Textbox->Text).ToPointer()) - James Hopkin
很好的建议,James。像你建议的那样,最好使用C++转换! - jdehaan

3
#include <string>
#include <iostream>
#include <atlbase.h>
#include <atlconv.h>
#include <vcclr.h>

using namespace System;

int main(array<System::String ^> ^args)
{
    String^ managedStr = gcnew String(L"Hello, Managed string!");
    //If you want to convert to wide string
    pin_ptr<const wchar_t> wch = PtrToStringChars(managedStr);
    std::wstring nativeWstr(wch);
    //if you want to convert to std::string without manual resource cleaning
    std::string nativeStr(CW2A(nativeWstr.c_str()));
    std::cout<<nativeStr<<std::endl;
    Console::WriteLine(L"Hello World");
    return 0;
}

2

感谢jdehaan。我稍微修改了代码,以便将其与我的“普通”System::String一起使用。

void MarshalNetToStdString(System::String^ s, std::string& os)
{
    using System::IntPtr;
    using System::Runtime::InteropServices::Marshal;

    const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer( );
    os = chars;
    Marshal::FreeHGlobal(IntPtr((void*)chars));
}

如果你想将System:String 转换为std:string,以下是步骤:


0

您可以将其转换为CString,然后添加扩展名。

有一个内置的CString构造函数可以完成这种转换

示例:

CString(Textbox->Text)

在你的具体情况下:
private: System::Void Button_Click(System::Object^ sender, System::EventArgs^ e) 
{
    ofstream myfile (CString(Textbox->Text) + ".txt"); 
    myfile.close(); 
}

你有没有任何线索为什么它会返回“CString:未找到标识符”,当我已经包含了string.h头文件? - Reznor
CString是MFC库的一部分 - 该项目是否使用MFC(我猜测它没有)?(项目属性/配置属性/常规/MFC的使用) - Ruddy
如果我选择“在静态库中使用MFC”,那么它会返回:“命令行错误D8016:‘/MT’和‘/clr:pure’命令行选项不兼容”。抱歉,我有点新手,这让我很烦恼。 - Reznor
是的,为了使用MFC,您需要更改/CLR设置并删除pure(项目属性/配置属性/常规/公共语言运行时支持)-在我的情况下这不是问题,如果对于您的项目而言是问题,您将无法使用MFC(据我所知)-可能有类似的包装器可以在没有MFC的情况下使用,但我还不知道(而不是像jdehaan提供的直接处理封送的方式-或者您可以自己编写)。 - Ruddy
这个页面http://msdn.microsoft.com/en-us/library/1b4az623.aspx可能会有用 - 它将CLR String ^转换为STL 字符串,不需要任何MFC并且封装了转换和内存处理。 - Ruddy

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接