Outils pour utilisateurs

Outils du site


lang:csharp:clr

Syntaxe de C++/CLI

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.

C# => C++

Pointeurs

Managed C++/CLI Array Conversion Error Archive du 01/09/2014 le 13/12/2019

  • C#
CalcSumArray(new[] { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f }, 6);
  • CLR

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.

pin_ptr (C++/CLI) Archive du 12/10/2018 le 13/12/2019

static float CalcSumArray(array<float>^ val, int length)
{
  cli::pin_ptr<float> t = &val[0];
  float* y = t;
  return SumArray(y, length);
}
  • C++
float SumArray(float* val, int length);

Marshaling

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

C++ => C#

Marshaling

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

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é
}

Prototype

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

Erreurs

  • '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

lang/csharp/clr.txt · Dernière modification : 2019/12/13 15:17 de root