Kompilator wywala: error C3145: 'Mode' : global or static variable may not have managed type 'System::String '.
Czyli: Zmienna globalna lub statyczna nie może mieć zarządzanego typu 'System::String '.
Chyba dość jasne?
Dla porównania deklaracja np. Int32 test przechodzi bez problemu zatem czemu nie pasuje mu String? Próbowałem deklarować w innych miejscach projektu ale bezskutecznie.
Bo System::Int32
to value
-type, a `System::String` to <code noframe>ref
-type. Te drugie mogą być tylko w klasie zarządzanej (ref class
/ref struct
/value class
/value struct
).
Rozwiązaniem jest:
• użycie stringa natywnego std::string
• użycie <code noframe>String^
wewnątrz klasy zarządzanej
• użycie auto_gcroot
, ale to berzyydkie jest:
```cpp
using namespace System;
#include <msclr\auto_gcroot.h>
using namespace msclr;
int main()
{
auto_gcroot<String^> str2; // natywne opakowanie dla typu zarządzanego
str2.attach(gcnew String("foo bar baz"));
auto_gcroot<String^> str1(gcnew String("ala ma kota")); // attach od razu przy konstrukcji
Console::WriteLine(str2.get()); // get() pobiera zawarty obiekt
Console::WriteLine(str2.get()->Length);
Console::WriteLine(str2->Length); // to samo co powyższe: przeciążony operator ->
str1.release(); // zwalnia zawarty String^, oddając go garbage collectorowi
/* wyższa filozofia: auto_gcroot na stercie */
auto_gcroot<String^> *str3 = new auto_gcroot<String^>(gcnew String("ali kot zdechl"));
Console::WriteLine(str3->get());
Console::WriteLine(str3->get()->Length);
//Console::WriteLine(str3->Length); // błąd: Length nie jest elementem str3
Console::WriteLine((*str3)->Length); // trzeba go zmusić do przeciążenia operatora
delete str3; // przy okazji zwolni zawartego stringa
// tutaj następuje zniszczenie str1 (ale sam String^ zwolniono uprzednio)
// obiekt zawarty w str2 też jest zwalniany, wraz z destrukcją str2.
}