Неуправляемый DLLs в C++

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

Мой AMI - Amazon Linux AMI ( https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/ ). Он имеет виртуализацию HVM и корневой том EBS. Первый шаг - сделать резервную копию корневого тома (или создать образ из существующего экземпляра). Затем я запускаю «sudo yum update» и перезапускаю экземпляр, чтобы посмотреть, все ли в порядке.

На ami уже были установлены модули ENA и NVMe. В / etc / fstab уже включен формат uuid.

To check ENA : modinfo ena
To check NVMe : modinfo nvme
To check whether ena driver is loaded on eth0 : ethtool -i eth0 and on eth1: ethtool -i eth1

Выполнение сценария https://github.com/awslabs/aws-support-tools/tree/master/EC2/C5M5InstanceChecks вернуло успех.

После этого я установил интерфейс командной строки AWS ( https://github.com/aws/aws-cli ) и настроил клиент с ключом доступа AWS, секретным ключом и регионом.

Затем я запускаю ec2 description-instances --instance-ids INSTANCE_ID --query "Reservations []. Instances []. EnaSupport"

Возвращается ответ "[]" (Согласно документации команда должна вернуть false).

Затем я остановил экземпляр и запустил следующую команду из AWS cli: ec2 modify-instance-attribute --instance-id INSTANCE_ID --ena-support

Я запустил сервер и выходные данные ethtool -i eth0 и ethtool -i eth1 показали, что оба моих интерфейса теперь имеют драйвер «ena».

Затем я остановил экземпляр и изменил тип экземпляра на t3.medium.

Ссылка ниже очень полезна: https://forums.aws.amazon.com/thread.jspa?threadID=290005 (ответ njohari-aws).

8
задан Peter C. 25 October 2008 в 07:04
поделиться

4 ответа

Я не могу подчеркнуть это достаточно, компилятор C++ не видит заголовочные файлы, после того, как препроцессор сделан, существует всего один большой исходный файл (также назван единицей компиляции). Так строго Вам не нужен заголовок для экспорта этой функции из dll. То, в чем Вы действительно нуждаетесь, является некоторой формой условной компиляции для экспорта функции в dll, который Вы компилируете и импортировать ее в клиентском коде.

Обычно это сделано с комбинацией макросов и заголовочных файлов. Вы создаете макрос под названием MYIMPORTEXPORT и с помощью макро-условных операторов, Вы заставляете его работать как __ declspec (dllexport) в dll, и __ declspec (dllimport) в клиентском коде.

в файле MYIMPORTEXPORT.h

#ifdef SOME_CONDITION
#define MYIMPORTEXPORT __declspec( dllexport )
#else
#define MYIMPORTEXPORT __declspec( dllimport )
#endif

в файле MyHeader.h

#include <MyImportExport.h>

MYIMPORTEXPORT public int calculateSquare(int num)
{
    return num*num;
}

в dll .cpp файл

#define SOME_CONDITION

#include <MyHeader.h>

в клиенте кодируют .cpp файл

#include <MyHeader.h>

Конечно, также необходимо предупредить компоновщика о создании dll с / опцией DLL.

Процесс сборки также сделает .lib файл, это - статический lib - назвал тупик в этом случае - который клиентский код должен связать с тем, как будто он связывался с реальным статическим lib. Автоволшебно, dll будет загружен, когда клиентский код будет выполнен. Конечно, dll должен быть найден ОС через ее механизм поиска, что означает, что Вы не можете поместить dll просто нигде, но в определенном месте. Вот находится больше на этом.

Очень удобный инструмент, чтобы видеть, экспортировали ли Вы корректную функцию из dll, и импортирует ли клиентский код правильно, является dumpbin. Выполните его с ЭКСПОРТОМ / и ИМПОРТОМ / соответственно.

15
ответ дан 5 December 2019 в 07:37
поделиться

Необходимо экспортировать функцию с помощью также__declspec( dllexport ) или добавление функции в файл определения модуля (.def). Затем скомпилируйте tho проект как DLL.

На стороне клиента у Вас есть две опции. Любой пользуется библиотекой импорта (.lib), который сгенерирован при компиляции DLL. Просто соединение с Вашим клиентским проектом с этой библиотекой предоставит Вам доступ к функциям, экспортируемым из DLL. И Вам нужен заголовочный файл, потому что компилятор должен знать подпись Вашей функции - что это возвращает интервал и берет интервал. Напомним, необходимо связаться с библиотекой импорта (.lib) и заголовочным файлом, который содержит заголовок функции.

Иначе должен загрузить DLL динамично с помощью WinAPI звонить LoadLibrary и затем GetProcAddress получить указатель на функцию. Указатель на функцию должен иметь корректный тип, так, чтобы компилятор мог дать его он, корректные параметры и корректное соглашение о вызовах используются.

0
ответ дан 5 December 2019 в 07:37
поделиться

QBziZ' ответ является достаточно правильным. Посмотрите Неуправляемый DLLs в C++

Завершать его: В C++, если необходимо использовать символ, необходимо сказать компилятору, что он существует, и часто, его прототип.

На других языках компилятор просто исследует библиотеку самостоятельно и найдет символ, и voilà.

В C++ необходимо сказать компилятор.

См. заголовок C/C++ как книжное оглавление

Лучший способ состоит в том, чтобы положить на некоторое общее место необходимый код. "Интерфейс", если Вы хотите. Это обычно делается в заголовочном файле, названном заголовком, потому что это обычно - не независимый исходный файл. Заголовок является только файлом, цель которого состоит в том, чтобы быть включена (т.е. копировать/вставлять препроцессором) в истинные исходные файлы.

По сути, кажется, что необходимо объявить дважды символ (функция, класс, безотносительно). Который является почти ересью по сравнению с другими языками.

Необходимо рассматривать его как книгу со сводной таблицей или индексом. В таблице у Вас есть все главы. В тексте у Вас есть главы и их содержание.

И иногда, Вы просто рады, что у Вас есть список главы.

В C++ это - заголовок.

Что относительно DLL?

Так, назад к проблеме DLL: цель DLL состоит в том, чтобы экспортировать символы, которые будет использовать Ваш код.

Так, в C++ путь необходимо оба экспортировать код при компиляции (т.е. в Windows, используйте __ declspec, например), и "опубликуйте" таблицу того, что экспортируется (т.е. имейте "общедоступные" заголовки, содержащие экспортируемые объявления).

6
ответ дан 5 December 2019 в 07:37
поделиться

Контрольный список для экспорта функций:

  • Действительно ли соглашение о вызовах подходит для вызывающей стороны? (это определяет, как передаются параметры и результаты, и кто ответственен за чистку стека). Необходимо заявить соглашение о вызовах explicitely.
  • Под которым именем будет экспортироваться символ? C++ обычно должен украшать ("искажают") названия символов, например, различать различные перегрузки.
  • Скажите компоновщику делать функцию видимой как Экспорт DLL

На MSVC:

  • __stdcall (который является соглашением о вызовах Паскаля), типичное соглашение о вызовах для экспортируемых символов - поддерживаемый большинством клиентов, которые я предполагаю.
  • экстерн "C" позволяет Вам экспортировать C-стиль символа без искажения имени
  • использовать __declspec(dllexport) для маркировки символа, который будет экспортироваться или свяжет отдельный .def файл, где, символы, которые будут экспортироваться, перечислены. С .def файлом можно также экспортировать ординалом только (не по имени) и изменить имя символа, который экспортируется.
1
ответ дан 5 December 2019 в 07:37
поделиться
Другие вопросы по тегам:

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