방법: 어셈블리에서 사용 되는 STL/CLR 컨테이너를 노출 합니다.
STL/CLR 컨테이너 등 list 및 map 템플릿 ref 클래스로 구현 됩니다.C + + 템플릿과 컴파일할 때 인스턴스화되지 않으므로 시그니처가 정확히 동일 하지만 다른 어셈블리에 있는 두 개의 템플릿 클래스 실제로 서로 다른 형식입니다.따라서 템플릿 클래스는 어셈블리에 걸쳐 사용할 수 없습니다.
STL/CLR 컨테이너 어셈블리 간 공유 가능 하 게 하려면 제네릭 인터페이스를 구현 ICollection<T>.제네릭은 C++, C# 및 Visual Basic 비롯 하 여, 지 원하는 모든 언어가 제네릭 인터페이스를 사용 하 여 STL/CLR 컨테이너에 액세스할 수 있습니다.
이 항목에서는 명명 된 C++ 어셈블리에 작성 된 여러 STL/CLR 컨테이너의 요소를 표시 하는 방법을 보여 줍니다 StlClrClassLibrary.우리 두 어셈블리가 표시 StlClrClassLibrary.첫 번째 어셈블리 C++, 및 두 번째 C#에 기록 됩니다.
두 어셈블리 C++로 작성 한 경우에 사용 하 여 제네릭 인터페이스 컨테이너에 액세스할 수 있습니다 해당 generic_container 형식 정의 합니다.예를 들어, 컨테이너 형식의 경우 cliext::vector<int>, 다음 해당 제네릭 인터페이스: cliext::vector<int>::generic_container.마찬가지로, 반복기는 제네릭 인터페이스를 사용 하 여 까는 generic_iterator 같이 typedef: cliext::vector<int>::generic_iterator.
이러한 형식 정의 C++ 헤더 파일에 선언 되어 있으므로 다른 언어로 작성 된 어셈블리를 사용할 수 없습니다.따라서 제네릭 인터페이스에 액세스 하려면 cliext::vector<int> C# 또는 다른.NET 언어를 사용 System.Collections.Generic.ICollection<int>.이 컬렉션을 통해 반복 하는 데 사용 하는 foreach 루프.
다음 표에서 각 STL/CLR 컨테이너를 구현 하는 제네릭 인터페이스를 보여 줍니다.
STL/CLR 컨테이너 |
제네릭 인터페이스 |
---|---|
있지 않은 deque <T> |
ICollection <T> |
< K, V > hash_map |
IDictionary < K, V > |
< K, V > hash_multimap |
IDictionary < K, V > |
hash_multiset <T> |
ICollection <T> |
hash_set <T> |
ICollection <T> |
<T> 목록 |
ICollection <T> |
< V K > 지도 |
IDictionary < K, V > |
multimap < K, V > |
IDictionary < K, V > |
복수 집합 <T> |
ICollection <T> |
<T>를 설정 합니다. |
ICollection <T> |
벡터 <T> |
ICollection <T> |
[!참고]
때문에 queue, priority_queue, 및 stack 컨테이너는 반복기를 지원 하지 않습니다, 제네릭 인터페이스를 구현 하 고 액세스 어셈블리 간 수 없습니다.
예제 1
설명
이 예에서는 STL/CLR 멤버의 개인 데이터를 포함 하는 C++ 클래스를 선언 합니다.에서는 다음 클래스의 개인 컬렉션에 대 한 액세스 권한을 부여 하는 공용 메서드를 선언 합니다.우리는 서로 대 한 두 가지 방법으로, C++ 클라이언트에 대해 수행합니다.NET 클라이언트입니다.
코드
// 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;
};
}
예제 2
설명
이 예제에서 우리가 예제 1에서 선언 하는 클래스를 구현 합니다.이 클래스 라이브러리를 사용 하는 클라이언트에 대 한 순서 대로 우리가 매니페스트 도구 사용 mt.exe DLL에 매니페스트 파일을 포함 합니다.자세한 내용은 코드 주석을 참조 하십시오.
Side-by-side 어셈블리 및 매니페스트 도구에 대 한 자세한 내용은 C/C++ 격리된 응용 프로그램 및 side-by-side 어셈블리 빌드.
코드
// 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;
}
}
예제 3
설명
이 예제에서는 예제 1과 2에서 만든 클래스 라이브러리를 사용 하는 C++ 클라이언트 우리를 만듭니다.이 클라이언트를 사용 하 여 generic_container typedef STL/CLR 컨테이너는 컨테이너를 통해 반복 하 고 해당 내용을 표시 합니다.
코드
// 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
예제 4
설명
이 예제에서는 예제 1과 2에서 만든 클래스 라이브러리를 사용 하는 C# 클라이언트 우리를 만듭니다.이 클라이언트를 사용 하 여 ICollection<T> 메서드는 STL/CLR 컨테이너는 컨테이너를 통해 반복 하 고 해당 내용을 표시 합니다.
코드
// 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