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 types
Il 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