Les types C# se postfixe avec un ^ et on utilise using namespace à la place de using pour faire la différence avec le C++.
using namespace System::Threading; Mutex^ mutex;
Une classe est autorisée à utiliser les types C# si sa déclaration est précédée de ref.
public ref class Carte {}
L'initialisation des variables statiques d'une classe doit se faire dans l'entête et l'allocation mémoire se faire avec un gcnew.
public ref class Driver { static System::Collections::Generic::List<Carte^>^ cartes = gcnew System::Collections::Generic::List<Carte^>();
La notion de référence & n'existe pas pour les objets managés.
Managed C++/CLI Array Conversion Error Archive du 01/09/2014 le 13/12/2019
CalcSumArray(new[] { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f }, 6);
C'est cli::pin_ptr qui fait office de GC::StillAlive() et donc val ne sera pas purgé tant que pin_ptr est en vie.
An object is pinned only while a pin_ptr points to it. The object is no longer pinned when its pinning pointer goes out of scope, or is set to nullptr. After the pin_ptr goes out of scope, the object that was pinned can be moved in the heap by the garbage collector.
static float CalcSumArray(array<float>^ val, int length) { cli::pin_ptr<float> t = &val[0]; float* y = t; return SumArray(y, length); }
float SumArray(float* val, int length);
| From type | To type | Marshal method | Include file |
|---|---|---|---|
| System::String^ | const char * | marshal_context | marshal.h |
| System::String^ | const wchar_t* | marshal_context | marshal.h |
| System::IntPtr | HANDLE | marshal_as | marshal_windows.h |
| System::String^ | BSTR | marshal_context | marshal_windows.h |
| System::String^ | bstr_t | marshal_as | marshal_windows.h |
| System::String^ | std::string | marshal_as | marshal_cppstd.h |
| System::String^ | std::wstring | marshal_as | marshal_cppstd.h |
| System::String^ | CStringT<char> | marshal_as | marshal_atl.h |
| System::String^ | CStringT<wchar_t> | marshal_as | marshal_atl.h |
| System::String^ | CComBSTR | marshal_as | marshal_atl.h |
Exemple :
#include <msclr\marshal_cppstd.h> System::String^ managed = "test"; std::string unmanaged = msclr::interop::marshal_as<std::string>(managed);
Overview of Marshaling in C++ Archive du 12/07/2019 le 13/12/2019
| From type | To type | Marshal method | Include file |
|---|---|---|---|
| const char * | System::String^ | marshal_as | marshal.h |
| char * | System::String^ | marshal_as | marshal.h |
| const wchar_t * | System::String^ | marshal_as | marshal.h |
| wchar_t * | System::String^ | marshal_as | marshal.h |
| HANDLE | System::IntPtr | marshal_as | marshal_windows.h |
| BSTR | System::String^ | marshal_as | marshal.h |
| bstr_t | System::String^ | marshal_as | marshal_windows.h |
| std::string | System::String^ | marshal_as | marshal_cppstd.h |
| std::wstring | System::String^ | marshal_as | marshal_cppstd.h |
| CStringT<char> | System::String^ | marshal_as | marshal_atl.h |
| CStringT<wchar_t> | System::String^ | marshal_as | marshal_atl.h |
| CComBSTR | System::String^ | marshal_as | marshal_atl.h |
struct Argument { int age; char name[50]; } ;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct Argument { public int age; [MarshalAs(UnmanagedType.LPStr, SizeConst = 50)] public string name; // fixed char name[50]; // Autre possibilité }
| C++/CLI | C# généré |
|---|---|
uint8_t | byte |
array<uint8_t>^ | byte[] |
System::String^ | string |
System::String^% | ref string |
[System::Runtime::InteropServices::Out]System::String^% | out string |
[System::Runtime::InteropServices::In]System::String^% | ref string |
float | float |
float& | float* |
float% | ref float |
'IServiceProvider': ambiguous symbol
Il ne faut pas mettre using namespace System; avant la déclaration de #include <msclr/marshal_cppstd.h>.
'msclr::interop::marshal_as': none of the 3 overloads could convert all the argument typesIl ne faut pas tenter d'utiliser directement un attribut d'une classe. Il faut passer par une variable locale :
System::String^ fic = fichier_; std::string tt = msclr::interop::marshal_as<std::string>(fic);
'XXX.YYY(?)' is not supported by the language
Apparaît dans le projet C# en essayant d'appeler une fonction du projet C++/CLI. Dans le projet C++/CLI, il manque le ^ après le type à la place du ?.
Fixing "ambiguous symbol" in a C++/CLR project Archive du 11/07/2008 le 13/12/2019