Экспорт классов, содержащих станд.:: объекты (вектор, карта, и т.д.) от dll

Обведите массив и добавьте каждый к объекту:

const items = [{
    "S.N.": "1",
    "ITEM": "CIGARETTES",
    " QUANTITY SOLD ": " 3,603,221 ",
    "UNIT OF MEASURE": "CARTONS"
  },
  {
    "S.N.": "2",
    "ITEM": "LIQUOR",
    " QUANTITY SOLD ": " 5,680,586 ",
    "UNIT OF MEASURE": "BOTTLES"
  },
  {
    "S.N.": "3",
    "ITEM": "BEER",
    " QUANTITY SOLD ": " 7,581,446 ",
    "UNIT OF MEASURE": "CANS"
  }
]

const output = {}

items.forEach(i => {
  output[i.ITEM] = i
})

console.log(output)

58
задан etarion 13 September 2016 в 09:27
поделиться

9 ответов

Когда вы прикасаетесь к члену вашего класса с клиента, вам необходимо предоставить DLL-интерфейс. DLL-интерфейс означает, что компилятор создает функцию в самой DLL и делает ее импортируемой.

Поскольку компилятор не знает, какие методы используются клиентами класса DLL_EXPORTED, он должен обеспечить, чтобы все методы были dll -exported. Необходимо обеспечить, чтобы все члены, к которым могут обращаться клиенты, также должны экспортировать свои функции с помощью dll. Это происходит, когда компилятор предупреждает вас о методах, которые не были экспортированы, и компоновщик клиента отправляет ошибки.

Не каждый член должен быть отмечен с помощью dll-export, например, закрытые члены, недоступные для клиентов. Здесь вы можете игнорировать / отключать предупреждения (остерегайтесь сгенерированных компилятором dtor / ctors).

В противном случае члены должны экспортировать свои методы. Форвардное объявление их с помощью DLL_EXPORT не экспортирует методы этих классов. Вы должны пометить соответствующие классы в их модуле компиляции как DLL_EXPORT.

Что сводится к ... (для не экспортируемых в dll членов)

  1. Если у вас есть члены, которые не / не могут быть используется клиентами, отключите предупреждение.

  2. Если у вас есть члены, которые должны использоваться клиентами, создайте оболочку dll-export или создайте методы косвенного обращения.

  3. Чтобы сократить количество видимых извне элементов, используйте подходы, такие как как идиома PIMPL .


template class DLL_EXPORT std::allocator<tCharGlyphProviderRef>;

Это создает конкретизацию специализации шаблона в текущем модуле компиляции. Таким образом, это создает методы std :: allocator в dll и экспортирует соответствующие методы. Это не работает для конкретных классов, так как это только создание экземпляров шаблонных классов.

54
ответ дан 24 November 2019 в 18:57
поделиться

Одна альтернатива, которую, кажется, мало кто рассматривает, - это вообще не использовать DLL, а статически связывать со статической. Библиотека LIB. Если вы сделаете это, все проблемы экспорта / импорта исчезнут (хотя у вас все равно будут проблемы с именами, если вы используете разные компиляторы). Конечно, вы теряете функции архитектуры DLL, такие как загрузка функций во время выполнения, но во многих случаях это может быть небольшой ценой.

5
ответ дан 24 November 2019 в 18:57
поделиться

В таких случаях рассмотрите использование идиомы pimpl. Скрыть все сложные типы за одну пустоту *. Компилятор обычно не замечает, что ваши члены являются частными и все методы включены в DLL.

1
ответ дан 24 November 2019 в 18:57
поделиться

That warning is telling you that users of your DLL will not have access to your container member variables across the DLL boundary. Explicitly exporting them makes them available, but is it a good idea?

In general, I'd avoid exporting std containers from your DLL. If you can absolutely guarantee your DLL will be used with the same runtime and compiler version you'd be safe. You must ensure memory allocated in your DLL is deallocated using the same memory manager. To do otherwise will, at best, assert at runtime.

So, don't expose containers directly across DLL boundaries. If you need to expose container elements, do so via accessor methods. In the case you provided, separate the interface from the implementation and expose the inteface at the DLL level. Your use of std containers is an implementation detail that the client of your DLL shouldn't need to access.

Alternatively, do what Neil suggest and create a static library instead of a DLL. You lose the ability to load the library at runtime, and consumers of your library must relink anytime you change your library. If these are compromises you can live with, a static library would at least get you past this problem. I'll still argue you're exposing implementation details unnecessarily but it might make sense for your particular library.

17
ответ дан 24 November 2019 в 18:57
поделиться

If you use a DLL make initialization of all objects at event "DLL PROCESS ATTACH" and export a pointer to its classes/objects.
You may provide specific functions to create and destroy objects and functions to obtain the pointer of the objects created, so you can encapsulate these calls in a wrapper class of access at include file.

0
ответ дан 24 November 2019 в 18:57
поделиться

Нашел эту статью . Короче говоря, у Аарона есть «настоящий» ответ выше; Не открывайте стандартные контейнеры за пределами библиотеки.

4
ответ дан 24 November 2019 в 18:57
поделиться

Хотя этот поток довольно старый, я недавно обнаружил проблему, которая заставила меня снова задуматься о наличии шаблонов в моих экспортированных классах:

Я написал класс, у которого был частный член типа std :: map. Все работало достаточно хорошо, пока не было скомпилировано в режиме выпуска, даже при использовании в системе сборки, которая гарантирует, что все настройки компилятора одинаковы для всех целей. Карта была полностью скрыта, и ничего не было открыто для клиентов.

В результате код просто падал в режиме выпуска. Думаю, потому что для реализации и клиентского кода были созданы разные бинарные экземпляры std :: map.

Я полагаю, что в стандарте C ++ ничего не говорится о том, как это следует обрабатывать для экспортируемых классов, поскольку это в значительной степени зависит от компилятора.

3
ответ дан 24 November 2019 в 18:57
поделиться

Ни один из вышеперечисленных обходных путей неприемлем для MSVC из-за статических элементов данных внутри классов шаблонов, таких как контейнеры stl

, каждый модуль (dll / exe) получает свою собственную копию каждого статического определения ... вау! это приведет к ужасным вещам, если вы каким-то образом «экспортируете» такие данные (как «указано» выше) ... так что не пытайтесь делать это дома

см. http://support.microsoft.com/kb / 172396 / ru-us

0
ответ дан 24 November 2019 в 18:57
поделиться

Там другие вопросы.

Некоторые контейнеры STL «безопасны» для экспорта (например, векторные), а некоторые нет (например, карта).

Например, карта небезопасна, потому что она (во всяком случае, в дистрибутиве MS STL) содержит статический член с именем _Nil, значение которого сравнивается в итерации для проверки на конец. Каждый модуль, скомпилированный с помощью STL, имеет различное значение для _Nil, поэтому карта, созданная в одном модуле, не будет повторяться из другого модуля (она никогда не обнаруживает конец и взрывается).

Это применимо, даже если вы статически ссылаетесь на библиотеку, поскольку вы никогда не можете гарантировать, каким будет значение _Nil (оно не инициализировано).

Я считаю, что STLPort этого не делает.

7
ответ дан 24 November 2019 в 18:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: