marshal_as, строки и поля и свойства - PullRequest
5 голосов
/ 07 сентября 2010

включает "stdafx.h"

#include <string>
#include <msclr/marshal_cppstd.h>

ref class Test {
    System::String^ text;
    void Method() {
        std::string f = msclr::interop::marshal_as<std::string>(text); // line 8
    }
};

Этот код при компиляции с VS2008 дает:

.\test.cpp(8) : error C2665: 'msclr::interop::marshal_as' : none of the 3 overloads could convert all the argument types
        f:\programy\vs9\vc\include\msclr\marshal.h(153): could be '_To_Type msclr::interop::marshal_as<std::string>(const char [])'
        with
        [
            _To_Type=std::string
        ]
        f:\programy\vs9\vc\include\msclr\marshal.h(160): or       '_To_Type msclr::interop::marshal_as<std::string>(const wchar_t [])'
        with
        [
            _To_Type=std::string
        ]
        f:\Programy\VS9\VC\include\msclr/marshal_cppstd.h(35): or       'std::string msclr::interop::marshal_as<std::string,System::String^>(System::String ^const &)'
        while trying to match the argument list '(System::String ^)'

Но когда я изменяю поле на свойство:

    property System::String^ text;

тогда этот код компилируется без ошибок. Почему?

Ответы [ 3 ]

6 голосов
/ 01 мая 2012

Обходной путь должен сделать копию как это:

ref class Test {
    System::String^ text;
    void Method() {
        System::String^ workaround = text;
        std::string f = msclr::interop::marshal_as<std::string>(workaround);
    }
};
5 голосов
/ 07 сентября 2010

Ошибка, исправленная в VS2010. Элемент обратной связи здесь .

1 голос
/ 16 мая 2016

Я часто использую этот фрагмент, и он слишком громоздкий, чтобы объявлять новую переменную. Однако это тоже работает:

msclr::interop::marshal_as<std::string>(gcnew String(string_to_be_converted))

Еще один вариант, который работает для меня, это маленький шаблон. Он не только устраняет ошибку, обсуждаемую здесь, но и исправляет еще одну проблему, которая не работает с marshal_as, а именно то, что он не работает для ввода nullptr. Но на самом деле хорошим переводом c ++ для nullptr System :: String был бы .empty () std :: string (). Вот шаблон:

template<typename ToType, typename FromType>
inline ToType frum_cast(FromType s)
{
    if (s == nullptr)
        return ToType();
    return msclr::interop::marshal_as<ToType>(s);
}
...