如何将System::String^转换为std::string?

10

我是一名CLR开发者,在Visual C++中创建.NET DLL。

我尝试使用以下代码:

 static bool InitFile(System::String^ fileName, System::String^ container)
{
    return enc.InitFile(std::string(fileName), std::string(container));
}

我有一个编码器,通常会接收std :: string。但是在这里,如果我从std :: string中删除参数,则编译器(Visual Studio)会给出C2664错误和C2440错误,这两者实际上是相同的。VS告诉我,它无法将System :: String ^转换为std :: string。

所以我很难过... 我该怎么办才能将System :: String ^转换为std :: string?

更新:

现在,在您的帮助下,我有了这样的代码:

#include <msclr\marshal.h>
#include <stdlib.h>
#include <string.h>
using namespace msclr::interop;
namespace NSSTW
{
  public ref class CFEW
  {
 public:
     CFEW() {}

     static System::String^ echo(System::String^ stringToReturn)
    {
        return stringToReturn;  
    }

     static bool InitFile(System::String^ fileName, System::String^ container)
    {   
        std::string sys_fileName = marshal_as<std::string>(fileName);;
        std::string sys_container = marshal_as<std::string>(container);;
        return enc.InitFile(sys_fileName, sys_container);
    }
...

但是当我尝试编译时,出现了C4996错误。

错误C4996:'msclr::interop::error_reporting_helper<_To_Type,_From_Type>::marshal_as':该转换不受库支持,或者需要此转换的头文件未包括在内。请参考“如何扩展编组库”文档,以添加您自己的编组方法。

该怎么办呢?


4
你已经包含了msclr\marshal.h,尝试使用msclr\marshal_cppstd.h - Chris Schmich
@Chris Schmich:谢谢你 - 现在它可以完美编译 =) - Rella
4个回答

8
如果您使用的是VS2008或更新版本,则可以通过C++中添加的自动封送非常简单地实现此操作。例如,您可以通过marshal_asSystem::String^转换为std::string
System::String^ clrString = "CLR string";
std::string stdString = marshal_as<std::string>(clrString);

这是用于P/Invoke调用的相同的编组方法。

我喜欢这个想法,但是如何在我的代码中声明marshal_as?我应该在哪里写什么来声明它(以消除错误C2065),我使用的是VS2008。 - Rella
1
要将 System::String^ 转换为 std::string,您需要 #include <marshal_cppstd.h>,其中声明了 marshal_as - Chris Schmich
当我尝试使用#include <marshal_cppstd.h>时,它会给我一个致命错误C1083...所以我编辑了代码并在问题中发布了它(我使用了MS MSDN示例中使用的内容)...你能看一下吗? - Rella
抱歉,我有点偏离了,你需要包含 msclr\marshal_cppstd.h。你还遇到这个问题吗?你上面的代码仍然是 msclr\marshal.h - Chris Schmich
msclr\marshal.h也可以。顺便说一下,谢谢。 :) - Jakub Matczak

4

来自MSDN上的文章如何将System::String^转换为std::string或std::wstring

void MarshalString (String ^ s, string& os) 
{
    using namespace Runtime::InteropServices;
    const char* chars = 
      (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
    os = chars;
    Marshal::FreeHGlobal(IntPtr((void*)chars));
}

使用方法:

std::string a;
System::String^ yourString = gcnew System::String("Foo");
MarshalString(yourString, a);
std::cout << a << std::endl; // Prints "Foo"

3
您需要包含marshal_cppstd.h才能将String^转换为std::string。
如果您关心非ASCII字符,您并没有提到。如果您需要Unicode(如果不需要,为什么不需要!?),则有一个返回std::wstring的marshal_as。
如果您使用utf8,则必须自己编写代码。您可以使用简单的循环:
System::String^ s = ...;
std::string utf8; 
for each( System::Char c in s )
    // append encoding of c to "utf8";

1

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