Gewusst wie: Führen Sie einen STL/CLR-Container aus einer Assembly verfügbar
STL/CLR-Container wie list und map werden als Vorlagenref-Klassen implementiert.Da es sich um C++-Vorlagen zur Kompilierzeit instanziiert werden zwei Vorlagenklassen, die genau die gleiche Signatur haben jedoch in unterschiedlichen Assemblys sind eigentlich verschiedene Typen sind.Dies bedeutet, dass Vorlagenklassen nicht über Assembly hinweg verwendet werden können.
Um die Freigabe assemblyübergreifende ermöglichen, STL/CLR-Container ICollection<T> die generische Schnittstelle implementieren.Anhand dieser generische Schnittstelle verwenden, können alle Sprachen, einschließlich Generika C++, C# und Visual Basic unterstützen, STL/CLR-Container zugreifen.
In diesem Thema wird erläutert, wie die Elemente von mehreren STL/CLR-Container, die in eine Assembly mit dem Namen StlClrClassLibrary C++ geschrieben werden.Es sind zwei Assemblys auf, um StlClrClassLibrary zuzugreifen.Die erste Assembly wird in C++ und das zweite in C# geschrieben.
Wenn beide Assemblys in C++ geschrieben werden, können Sie die generische Schnittstelle einem Container zugreifen, indem Sie das generic_container typedef verwenden.Wenn Sie beispielsweise einen Container Typ cliext::vector<int> verfügen, dessen generische Schnittstelle ist: cliext::vector<int>::generic_container.Entsprechend können Sie einen Iterator über generische Schnittstelle abrufen, indem Sie generic_iterator, z. B. eine Typdefinition in verwenden: cliext::vector<int>::generic_iterator.
Da diese Typdefinitionen in C++-Headerdateien deklariert wurden, können die Assemblys, die in andere Sprachen geschriebene sie nicht verwenden.Daher die generische Schnittstelle für cliext::vector<int> in C# oder einer anderen .NET-Sprache zugreifen, verwenden Sie System.Collections.Generic.ICollection<int>.Um über diese Auflistung durchlaufen, verwenden Sie eine foreach Schleife.
In der folgenden Tabelle sind die generische Schnittstelle aufgelistet, die jeder STL/CLR-Container implementiert:
STL/CLR-Container |
Generische Schnittstellen |
---|---|
Doppelschlange<T> |
<T>ICollection |
hash_map<K und V> |
<K und V>IDictionary |
hash_multimap<K und V> |
<K und V>IDictionary |
hash_multiset<T> |
<T>ICollection |
hash_set<T> |
<T>ICollection |
Liste<T> |
<T>ICollection |
Zuordnung<K und V> |
<K und V>IDictionary |
Multimap<K und V> |
<K und V>IDictionary |
Multiset<T> |
<T>ICollection |
legen Sie fest<T> |
<T>ICollection |
Vektor<T> |
<T>ICollection |
Hinweis |
---|
Da queue, priority_queue und stack Container nicht Iteratoren unterstützen, implementieren sie nicht generische Schnittstellen und können nicht assemblyübergreifendes dass der Zugriff auf das Zielobjekt sein. |
Beispiel 1
Beschreibung
In diesem Beispiel müssen wir eine C++-Klasse, die private STL und CLR-Member Benutzerdaten enthält.Es wird dann öffentliche Methoden So erteilen Sie Zugriff auf die Privatsammlungen der Klasse.Wir führen diese auf zwei verschiedene Möglichkeiten, eine für C++-Clienten und eine andere für .NET-Clients können.
Code
// StlClrClassLibrary.h
#pragma once
#include <cliext/deque>
#include <cliext/list>
#include <cliext/map>
#include <cliext/set>
#include <cliext/stack>
#include <cliext/vector>
using namespace System;
using namespace System::Collections::Generic;
using namespace cliext;
namespace StlClrClassLibrary {
public ref class StlClrClass
{
public:
StlClrClass();
// These methods can be called by a C++ class
// in another assembly to get access to the
// private STL/CLR types defined below.
deque<wchar_t>::generic_container ^GetDequeCpp();
list<float>::generic_container ^GetListCpp();
map<int, String ^>::generic_container ^GetMapCpp();
set<double>::generic_container ^GetSetCpp();
vector<int>::generic_container ^GetVectorCpp();
// These methods can be called by a non-C++ class
// in another assembly to get access to the
// private STL/CLR types defined below.
ICollection<wchar_t> ^GetDequeCs();
ICollection<float> ^GetListCs();
IDictionary<int, String ^> ^GetMapCs();
ICollection<double> ^GetSetCs();
ICollection<int> ^GetVectorCs();
private:
deque<wchar_t> ^aDeque;
list<float> ^aList;
map<int, String ^> ^aMap;
set<double> ^aSet;
vector<int> ^aVector;
};
}
Beispiel 2
Beschreibung
In diesem Beispiel wird die Klasse implementieren, die in Beispiel 1. deklariert ist.Damit Clients verwenden diese Klassenbibliothek, werden vom Manifesttool mt.exe, die Manifestdatei in die DLL einzubetten.Weitere Informationen finden Sie in der Codekommentare.
Weitere Informationen zum Manifesttool und parallelen Assemblys finden Sie unter Erstellen von isolierten Anwendungen und parallelen Assemblys (C/C++).
Code
// StlClrClassLibrary.cpp
// compile with: /clr /LD /link /manifest
// post-build command: (attrib -r StlClrClassLibrary.dll & mt /manifest StlClrClassLibrary.dll.manifest /outputresource:StlClrClassLibrary.dll;#2 & attrib +r StlClrClassLibrary.dll)
#include "StlClrClassLibrary.h"
namespace StlClrClassLibrary
{
StlClrClass::StlClrClass()
{
aDeque = gcnew deque<wchar_t>();
aDeque->push_back(L'a');
aDeque->push_back(L'b');
aList = gcnew list<float>();
aList->push_back(3.14159f);
aList->push_back(2.71828f);
aMap = gcnew map<int, String ^>();
aMap[0] = "Hello";
aMap[1] = "World";
aSet = gcnew set<double>();
aSet->insert(3.14159);
aSet->insert(2.71828);
aVector = gcnew vector<int>();
aVector->push_back(10);
aVector->push_back(20);
}
deque<wchar_t>::generic_container ^StlClrClass::GetDequeCpp()
{
return aDeque;
}
list<float>::generic_container ^StlClrClass::GetListCpp()
{
return aList;
}
map<int, String ^>::generic_container ^StlClrClass::GetMapCpp()
{
return aMap;
}
set<double>::generic_container ^StlClrClass::GetSetCpp()
{
return aSet;
}
vector<int>::generic_container ^StlClrClass::GetVectorCpp()
{
return aVector;
}
ICollection<wchar_t> ^StlClrClass::GetDequeCs()
{
return aDeque;
}
ICollection<float> ^StlClrClass::GetListCs()
{
return aList;
}
IDictionary<int, String ^> ^StlClrClass::GetMapCs()
{
return aMap;
}
ICollection<double> ^StlClrClass::GetSetCs()
{
return aSet;
}
ICollection<int> ^StlClrClass::GetVectorCs()
{
return aVector;
}
}
Beispiel 3
Beschreibung
In diesem Beispiel erstellen wir Client in C++ erstellt, der die Klassenbibliothek verwendet, die in Beispiel 1 und 2 erstellt wird.Dieser Client verwendet die generic_container-Typdefinitionen der STL/CLR-Container über den Containern zu durchlaufen und deren Inhalt anzuzeigen.
Code
// CppConsoleApp.cpp
// compile with: /clr /FUStlClrClassLibrary.dll
#include <cliext/deque>
#include <cliext/list>
#include <cliext/map>
#include <cliext/set>
#include <cliext/vector>
using namespace System;
using namespace StlClrClassLibrary;
using namespace cliext;
int main(array<System::String ^> ^args)
{
StlClrClass theClass;
Console::WriteLine("cliext::deque contents:");
deque<wchar_t>::generic_container ^aDeque = theClass.GetDequeCpp();
for each (wchar_t wc in aDeque)
{
Console::WriteLine(wc);
}
Console::WriteLine();
Console::WriteLine("cliext::list contents:");
list<float>::generic_container ^aList = theClass.GetListCpp();
for each (float f in aList)
{
Console::WriteLine(f);
}
Console::WriteLine();
Console::WriteLine("cliext::map contents:");
map<int, String ^>::generic_container ^aMap = theClass.GetMapCpp();
for each (map<int, String ^>::value_type rp in aMap)
{
Console::WriteLine("{0} {1}", rp->first, rp->second);
}
Console::WriteLine();
Console::WriteLine("cliext::set contents:");
set<double>::generic_container ^aSet = theClass.GetSetCpp();
for each (double d in aSet)
{
Console::WriteLine(d);
}
Console::WriteLine();
Console::WriteLine("cliext::vector contents:");
vector<int>::generic_container ^aVector = theClass.GetVectorCpp();
for each (int i in aVector)
{
Console::WriteLine(i);
}
Console::WriteLine();
return 0;
}
Output
cliext::deque contents:
a
b
cliext::list contents:
3.14159
2.71828
cliext::map contents:
0 Hello
1 World
cliext::set contents:
2.71828
3.14159
cliext::vector contents:
10
20
Beispiel 4
Beschreibung
In diesem Beispiel erstellen wir einen C#-Clienten erstellt, der die Klassenbibliothek verwendet, die in Beispiel 1 und 2 erstellt wird.Dieser Client verwendet die ICollection<T>-Methoden der STL/CLR-Container über den Containern zu durchlaufen und deren Inhalt anzuzeigen.
Code
// CsConsoleApp.cs
// compile with: /r:Microsoft.VisualC.STLCLR.dll /r:StlClrClassLibrary.dll /r:System.dll
using System;
using System.Collections.Generic;
using StlClrClassLibrary;
using cliext;
namespace CsConsoleApp
{
class Program
{
static int Main(string[] args)
{
StlClrClass theClass = new StlClrClass();
Console.WriteLine("cliext::deque contents:");
ICollection<char> iCollChar = theClass.GetDequeCs();
foreach (char c in iCollChar)
{
Console.WriteLine(c);
}
Console.WriteLine();
Console.WriteLine("cliext::list contents:");
ICollection<float> iCollFloat = theClass.GetListCs();
foreach (float f in iCollFloat)
{
Console.WriteLine(f);
}
Console.WriteLine();
Console.WriteLine("cliext::map contents:");
IDictionary<int, string> iDict = theClass.GetMapCs();
foreach (KeyValuePair<int, string> kvp in iDict)
{
Console.WriteLine("{0} {1}", kvp.Key, kvp.Value);
}
Console.WriteLine();
Console.WriteLine("cliext::set contents:");
ICollection<double> iCollDouble = theClass.GetSetCs();
foreach (double d in iCollDouble)
{
Console.WriteLine(d);
}
Console.WriteLine();
Console.WriteLine("cliext::vector contents:");
ICollection<int> iCollInt = theClass.GetVectorCs();
foreach (int i in iCollInt)
{
Console.WriteLine(i);
}
Console.WriteLine();
return 0;
}
}
}
Output
cliext::deque contents:
a
b
cliext::list contents:
3.14159
2.71828
cliext::map contents:
0 Hello
1 World
cliext::set contents:
2.71828
3.14159
cliext::vector contents:
10
20