Поделиться через


Практическое руководство. Доступ к контейнеру STL/CLR из сборки

Контейнеры STL/CLR, как list и map реализованы как классы ref шаблона.Поскольку шаблоны C++ создается во время компиляции, 2 класса шаблона, имеют те же сигнатурой, но в разных сборках, фактически различные типы.Это означает, что классы шаблонов не может использоваться за пределами сборки.

Сделать возможным совместное использование крест-сборки, контейнеры реализуют интерфейс ICollection<T> STL/CLR универсальный шаблон.С помощью данного универсального интерфейса, все языки, поддерживающих универсальные шаблоны, включая C++, C# и Visual Basic, могут обращаться к контейнерам STL/CLR.

Этот раздел показывает, как отобразить элементы несколько контейнеров STL/CLR, записанных в C++ StlClrClassLibrary именованном сборкой.Мы показываем 2 сборки для доступа к StlClrClassLibrary.Первая сборка написана на языке C++ и втором в c#.

Если обе сборки создаются на C++, можно получить доступ к универсальный шаблон интерфейс контейнера с помощью его typedef generic_container.Например, если имеется контейнер типа cliext::vector<int>, то его универсальный шаблон интерфейс выглядит следующим образом: cliext::vector<int>::generic_container.Аналогично можно получить итератор над родовым интерфейсом с помощью typedef generic_iterator, например: cliext::vector<int>::generic_iterator.

Поскольку эти typedef, объявляются в файлах заголовка C++, сборки, написанных на других языках могут не использовать их.Следовательно, получить доступ универсальный шаблон интерфейс для cliext::vector<int> в C# или любом другом языке .NET, используйте System.Collections.Generic.ICollection<int>.Для выполнения итерации по этой коллекцией, используйте цикл foreach.

В следующей таблице перечислены универсальный шаблон интерфейс, каждый контейнер STL/CLR реализует:

Контейнер STL/CLR

Универсальный шаблон интерфейс

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>

список<T>

ICollection<T>

сопоставление<K И V>

IDictionary<K И V>

multimap<K И V>

IDictionary<K И V>

multiset<T>

ICollection<T>

установите<T>

ICollection<T>

вектор<T>

ICollection<T>

ПримечаниеПримечание

Поскольку queue, priority_queue и контейнеры stack не поддерживают итераторы они не реализуют родовые интерфейсы и не могут быть " крест-сборкой.

Пример 1

Bb385659.collapse_all(ru-ru,VS.110).gifОписание

В этом примере объявляем класс C++, содержащий личные данные элемента STL/CLR.Мы затем объявляем открытые методы, чтобы предоставить доступ к коллекциям частным класса.Мы делаем его в 2 различными способами, один для клиентов C++ и один для других клиентов .NET.

Bb385659.collapse_all(ru-ru,VS.110).gifКод

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

Bb385659.collapse_all(ru-ru,VS.110).gifОписание

В этом примере мы реализуем интерфейс класс, объявленный в примере 1.Для клиентов для использования этой библиотеки классов, инструмент манифеста mt.exe используется для внедрения файла манифеста библиотеки DLL.Дополнительные сведения см. в комментариях кода.

Дополнительные сведения о средстве манифестов и параллельных сборках см. в разделе Построение изолированных приложений и параллельных сборок C/C++.

Bb385659.collapse_all(ru-ru,VS.110).gifКод

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

Bb385659.collapse_all(ru-ru,VS.110).gifОписание

В этом примере создается клиент C++, использующий созданную библиотеку классов в примерах, 1 и 2.Этот клиент использует typedef generic_container контейнеров STL/CLR для перебора всех контейнеров и указывать их содержимое.

Bb385659.collapse_all(ru-ru,VS.110).gifКод

// 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(ru-ru,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

Пример 4

Bb385659.collapse_all(ru-ru,VS.110).gifОписание

В этом примере создается клиент c#, использующий созданную библиотеку классов в примерах, 1 и 2.Этот клиент использует методы ICollection<T> контейнеров STL/CLR для перебора всех контейнеров и указывать их содержимое.

Bb385659.collapse_all(ru-ru,VS.110).gifКод

// 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(ru-ru,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

См. также

Другие ресурсы

Ссылка библиотека STL/CLR