Sdílet prostřednictvím


Postupy: Vystavení kontejneru STL/CLR ze sestavení

Kontejnery STL/CLR, jako jsou například list a map jsou implementovány jako třídy ref šablony. Vzhledem k tomu, že šablony jazyka C++ se vytvářejí v době kompilace, dvě třídy šablon, které mají přesně stejný podpis, ale jsou ve skutečnosti různé typy. To znamená, že třídy šablon nelze použít přes hranice sestavení.

Aby bylo možné sdílení křížového sestavení, kontejnery STL/CLR implementují obecné rozhraní ICollection<T>. Pomocí tohoto obecného rozhraní mají všechny jazyky, které podporují obecné typy, včetně C++, C# a Visual Basicu, přístup ke kontejnerům STL/CLR.

Toto téma ukazuje, jak zobrazit prvky několika kontejnerů STL/CLR napsaných v sestavení C++ s názvem StlClrClassLibrary. Zobrazíme dvě sestavení pro přístup StlClrClassLibrary. První sestavení je zapsáno v jazyce C++ a druhé v jazyce C#.

Pokud jsou obě sestavení zapsána v jazyce C++, můžete získat přístup k obecnému rozhraní kontejneru pomocí jeho generic_container typedef. Například pokud máte kontejner typu cliext::vector<int>, pak jeho obecné rozhraní je: cliext::vector<int>::generic_container. Podobně můžete získat iterátor přes obecné rozhraní pomocí generic_iterator typedef, jako v: cliext::vector<int>::generic_iterator.

Vzhledem k tomu, že tyto definice typedefs jsou deklarovány v souborech hlaviček jazyka C++, sestavení zapsaná v jiných jazycích je nemohou použít. Proto pro přístup k obecnému rozhraní pro cliext::vector<int> jazyk C# nebo v jiném jazyce .NET použijte System.Collections.Generic.ICollection<int>. K iteraci této kolekce použijte smyčku foreach .

Následující tabulka uvádí obecné rozhraní, které každý kontejner STL/CLR implementuje:

Kontejner STL/CLR Obecné rozhraní
deque<T> ICollection<T>
hash_map<K, V> IDictionary<K, V>
hash_multimap<K, V> IDictionary<K, V>
hash_multiset<T> ICollection<T>
hash_set<T> ICollection<T>
list<T> ICollection<T>
map<K, V> IDictionary<K, V>
multimap<K, V> IDictionary<K, V>
multiset<T> ICollection<T>
set<T> ICollection<T>
vector<T> ICollection<T>

Poznámka:

Protože kontejnery queue, priority_queuea stack kontejnery nepodporují iterátory, neimplementují obecná rozhraní a nelze k nim přistupovat mezi sestaveními.

Příklad 1

Popis

V tomto příkladu deklarujeme třídu C++, která obsahuje privátní data členů STL/CLR. Pak deklarujeme veřejné metody pro udělení přístupu k privátním kolekcí třídy. Děláme to dvěma různými způsoby, jeden pro klienty C++ a druhý pro ostatní klienty .NET.

Kód

// 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;
    };
}

Příklad 2

Popis

V tomto příkladu implementujeme třídu deklarovanou v příkladu 1. Aby klienti mohli tuto knihovnu tříd používat, používáme nástroj manifestu mt.exe k vložení souboru manifestu do knihovny DLL. Podrobnosti najdete v komentářích ke kódu.

Další informace o nástroji manifestu a souběžných sestaveních naleznete v tématu Sestavení izolovaných aplikací C/C++ a souběžných sestavení.

Kód

// 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;
    }
}

Příklad 3

Popis

V tomto příkladu vytvoříme klienta C++, který používá knihovnu tříd vytvořenou v příkladech 1 a 2. Tento klient používá generic_container definice typedef kontejnerů STL/CLR k iteraci kontejnerů a k zobrazení jejich obsahu.

Kód

// 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;
}

Výstup

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

Příklad 4

Popis

V tomto příkladu vytvoříme klienta jazyka C#, který používá knihovnu tříd vytvořenou v příkladech 1 a 2. Tento klient používá ICollection<T> metody kontejnerů STL/CLR k iteraci kontejnerů a k zobrazení jejich obsahu.

Kód

// 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;
        }
    }
}

Výstup

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

Viz také

Referenční dokumentace knihoven STL/CLR