Condividi tramite


Procedura: Esporre un contenitore di STL/CLR da un assembly

I contenitori STL/CLR come list e map vengono implementati come classi di riferimento del modello.Poiché i modelli C++ viene creata un'istanza in fase di compilazione, due classi modello che hanno esattamente la stessa firma ma sono in assembly diversi sono effettivamente tipi diversi.Ciò significa che le classi modello non possono essere utilizzate nei limiti dell'assembly.

Per consentire la condivisione dell'croce-assembly, utilizzare i contenitori STL/CLR l'interfaccia generica ICollection<T>.Tramite questa interfaccia generica, tutti i linguaggi che supportano i generics, inclusi C++, c# e Visual Basic, possono accedere ai contenitori STL/CLR.

In questo argomento viene illustrato come visualizzare gli elementi di diversi contenitori STL/CLR scritto in C++ StlClrClassLibrarydenominato assembly.Verranno mostrati due assembly per accedere a StlClrClassLibrary.Il primo assembly viene scritto in C++ e nel secondo in c#.

Se gli assembly vengono scritti in C++, è possibile accedere all'interfaccia generica di un contenitore utilizzando il relativo typedef di generic_container .Ad esempio, se si dispone di un contenitore di tipo cliext::vector<int>, la relativa interfaccia generica è: cliext::vector<int>::generic_container.Analogamente, è possibile ottenere un iteratore su nell'interfaccia generica utilizzando il typedef di generic_iterator , come indicato di seguito: cliext::vector<int>::generic_iterator.

Poiché questi typedef sono dichiarati in un file di intestazione C++, gli assembly scritti in altri linguaggi non possano utilizzarli.Di conseguenza, accedere all'interfaccia generica per cliext::vector<int> in c# o qualsiasi altro linguaggio.NET, utilizzare System.Collections.Generic.ICollection<int>.Per scorrere la raccolta, utilizzare un ciclo di foreach .

Nella tabella seguente sono elencati l'interfaccia generica che ogni contenitore STL/CLR implementa:

Contenitore STL/CLR

Interfaccia generica

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>

elenco<t>

ICollection<t>

mapping<K, V>

IDictionary<K, V>

multimap<K, V>

IDictionary<K, V>

multi-insieme<t>

ICollection<t>

impostare<t>

ICollection<t>

vettore<t>

ICollection<t>

[!NOTA]

Poiché queue, priority_queuee i contenitori di stack non supportano gli iteratori, non implementano le interfacce generiche e non possono essere croce-assembly accesso.

Esempio 1

Bb385659.collapse_all(it-it,VS.110).gifDescrizione

In questo esempio, dichiariamo la classe C++ che contiene i dati dei membri privati STL/CLR.Quindi dichiariamo i metodi pubblici per concedere l'accesso alle raccolte di classe private.La facciamo in due modi diversi, uno per i client C++ e uno per altri client.NET.

Bb385659.collapse_all(it-it,VS.110).gifCodice

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

Esempio 2

Bb385659.collapse_all(it-it,VS.110).gifDescrizione

In questo esempio, implementiamo la classe dichiarata nell'esempio 1.In modo che i client di utilizzare questa libreria di classi, è possibile utilizzare lo strumento manifesto mt.exe per importare il file manifesto nella DLL.Per informazioni dettagliate, vedere i commenti del codice.

Per ulteriori informazioni sullo strumento manifesto e sugli assembly side-by-side, vedere Compilazione di applicazioni isolate C/C++ e di assembly side-by-side.

Bb385659.collapse_all(it-it,VS.110).gifCodice

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

Esempio 3

Bb385659.collapse_all(it-it,VS.110).gifDescrizione

In questo esempio, viene creato il client C++ che utilizza la libreria di classi creata nell'Esempio 1 e a 2.Questo client utilizzano i typedef di generic_container di contenitori STL/CLR per scorrere i contenitori e visualizzare i relativi contenuti.

Bb385659.collapse_all(it-it,VS.110).gifCodice

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

Bb385659.collapse_all(it-it,VS.110).gifOutput

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

Esempio 4

Bb385659.collapse_all(it-it,VS.110).gifDescrizione

In questo esempio, viene creato un client c# che utilizza la libreria di classi creata nell'Esempio 1 e a 2.Questo client utilizzano i metodi di ICollection<T> di contenitori STL/CLR per scorrere i contenitori e visualizzare i relativi contenuti.

Bb385659.collapse_all(it-it,VS.110).gifCodice

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

Bb385659.collapse_all(it-it,VS.110).gifOutput

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

Vedere anche

Altre risorse

Riferimenti alla libreria STL/CLR