Как сбросить ASP Страница запуска .NET?

заголовок экспорта dll

extern "C"
void _declspec(dllexport) __stdcall foo();

.def file

EXPORTS
foo         @1

Когда я собираю dll с помощью 64-битной конфигурации сборки, я встречаю это предупреждение.

предупреждение LNK4197: экспорт 'foo' указан несколько раз ; используя первую спецификацию

Но если я соберу dll с помощью 32-битной конфигурации, предупреждение никогда не появится.
В чем проблема? В чем разница.

В заголовке dll для интерфейса мы обычно используем эту технику,

#ifdef EXPORT_DLL
#define BASICAPI _declspec(dllexport)
#else
#define BASICAPI _declspec(dllimport)
#endif //_EXPORT_DLL

Но если файл def также существует, мы всегда будем встречать предупреждение при создании 64-битной dll.
Так стоит ли нам писать такие коды?

#ifdef EXPORT_DLL
#define BASICAPI
#else
#define BASICAPI _declspec(dllimport)
#endif //_EXPORT_DLL

Это работает хорошо. Но это мне не знакомо.
Дайте мне свое мнение.

9
задан Benjamin 26 August 2010 в 06:25
поделиться

2 ответа

Обычно указывать экспорт дважды для одной и той же функции не рекомендуется. Если у вас уже есть __declspec(dllexport), вам также не нужно указывать экспорт в файле .def.И наоборот, если экспорт указан в файле .def, то нет необходимости в __declspec(dllexport).

Я полагаю, что причина предупреждения заключается в том, что в сборках x86 __declspec(dllexport) экспортирует оформленное имя с начальным символом подчеркивания, но 64-разрядный компилятор не украшает имена начальным символом. подчеркивание, ведущее к дубликату. Чтобы убедиться в этом, вы можете посмотреть на 32-битную DLL в Dependency Walker, и вы должны увидеть две экспортированные функции, «foo» и «_foo».

11
ответ дан 4 December 2019 в 12:57
поделиться

__declspec(dllexport) и файлы .def — это два различных способа экспорта символов из dll. Вам не нужны оба, и вы должны опустить один из них. Метод __declspec гораздо более универсален для программ на С++, поскольку он экспортирует имена с исправлением С++, позволяя экспортировать перегруженные функции, но, наоборот, затрудняет импорт имен через GetProcAddress.

Кроме того, использование универсального макроса, такого как EXPORT_DLL, опасно, так как это означает, что вы не можете создать dll, использующую другую dll, без того, чтобы одна dll пыталась экспортировать все символы обеих dll. .

DevStudio автоматически создает символ для dll-проектов: _EXPORTS, что позволяет легко и безопасно создавать макрос EXPORT:

#ifdef EXPORT
#undef EXPORT
#endif
#ifdef PROJECTNAMEHERE_EXPORTS
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif

EXTERN_C EXPORT void __stdcall Function1(void);
EXTERN_C EXPORT void __cdecl Function2(...);
         EXPORT void Function3(void);

Функции 1 и 2 можно получить с помощью GetProcAddress как _Function1. @0 и Функция2 соответственно. Function3 будет экспортироваться с помощью измененного имени компилятора, которое будет выглядеть примерно так: @Function3@@UAG_DB@Z. Это имя отличается для каждой перегрузки функции, что позволяет перегрузке работать.

Важно знать искажение имени __declspec, так как файлы .def не имеют значения и будут просто экспортировать Функция1, Функция2 и Функция3 .

5
ответ дан 4 December 2019 в 12:57
поделиться
Другие вопросы по тегам:

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