C#托管代码和c ++非托管代码之间的字符串的混合编程

时间:2011-08-01 07:47:23

标签: c# wrapper unmanaged managed string-conversion

我正在开发一个c ++项目,该项目使用字符串路径来调用XML文件。当我编译c ++时,一切都运行良好,我能够使用XML文件,因为我的项目需要。

我需要使用C#GUI,所以我做了一个包装器来从我的C ++文件中调用所有函数。在两个平台之间调试之后出现一个问题,c#无法识别调用我的文件的字符串路径,我得到的错误是它无法找到给定的路径。有谁知道如何在两个平台之间发送有效的字符串路径?

提前致谢, 卡罗来纳州

    int ClassUnmanaged::ReadFile(string path_to_file)
     {
        int status = XMLClass->ReadConfigFile(path_to_file);

        if(status)
        {
           return status; //Error
        }

        else
        {
           return 0;
        }
    }

C ++类的Wrapper.h

    public __gc class Wrapper
    {

      public:   Wrapper(void);
      public:   ~Wrapper(void);
             /** Unmanaged pointer to Class Unmanaged API
               *    
               */
      private:  ClassUnmanaged__nogc* pointerUnmanaged;

          public: int NewReadfile(string path_to_file);
    }

Wrapper.cpp

    int Wrapper::NewReadFile(string path)
    {
        pointerUnmanaged->ReadFile(path);//here i access to my class unmanaged
    return 0;
     }

UI.cs

在UI.cs中,由于c ++使用的字符串类型,我无法从包装器调用函数NewReadfile。知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

您需要将NewReadFile方法更改为public,然后将其更改为将C#知道的类型作为输入,如Sytem::String它应该看起来像这样(使用新的托管C ++语法适应旧的如果需要的话)

int Wrapper::NewReadFile(System::String^ path)
{
    char* pathAsCharArray = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
    try
    {
        std::string pathAsStdString(pathAsCharArray);
        pointerUnmanaged->ReadFile(pathAsStdString);
    }
    finally
    {
        Marshal::FreeHGlobal(pathUnmanaged);
    }

    return 0;
 }

有一篇名为"How to convert from System::String* to Char* in Visual C++"的知识库文章解释了这个概念。如果您的底层API可以支持unicode并且您使用新语法,那么更好的方法是进行转换:

pin_ptr<const wchar_t> pathAsCharArray = PtrToStringChars(path);
std::wstring pathAsStrign(pathAsCharArray);