Как мне остановить изменение имени экспортируемой функции моей библиотеки DLL?

Я пытаюсь создать DLL, которая экспортирует функцию под названием «GetName». Я бы хотел, чтобы другой код мог вызывать эту функцию, не зная искаженного имени функции.

Мой заголовочный файл выглядит так:

#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif

EXPORT TCHAR * CALLBACK GetName();

Мой код выглядит так:

#include <windows.h>
#include "PluginOne.h"

int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
     return TRUE ;
}

EXPORT TCHAR * CALLBACK GetName()
{
    return TEXT("Test Name");
}

Когда я строю, DLL по-прежнему экспортирует функцию с именем: «_GetName @ 0».

Что я делаю неправильно?


person Slapout    schedule 23.09.2009    source источник


Ответы (4)


Небольшая поправка - для успешного разрешения name by Clinet

extern "C"

должно быть как при экспорте, так и при импорте.

extern «C» сократит имя процедуры до: «_GetName».

Более того, вы можете указать любое имя с помощью раздела ЭКСПОРТ в файле .def.

person Dewfy    schedule 23.09.2009
comment
Привет, круто, это именно то, что мне нужно. Что, если я хочу наоборот? У меня есть функция C, вполне нормально быть функцией-членом C ++ (vtable, соглашение о вызовах все выполнено), но компилятор считает, что ее имя должно быть искажено. - person Pyjong; 26.01.2015
comment
Да, C и C ++ используют разные правила оформления имен. Чтобы сделать то, о чем вы спрашиваете, вам нужно создать оболочку, которая будет вызывать функцию C из члена класса C ++. - person Dewfy; 27.01.2015
comment
Файл .DEF - единственный способ отключить искажение имен. extern "C" по-прежнему будет использовать оформление имен, но не так многословно, как того требует C ++. - person IInspectable; 20.04.2017

Это нормально для экспорта DLL с условием __stdcall. @N указывает количество байтов, которые функция принимает в свои аргументы - в вашем случае , нуль.

Обратите внимание, что страница MSDN при экспорте из библиотеки DLL в частности, говорится «использовать соглашение о вызовах __stdcall» при использовании «ключевого слова __declspec (dllexport) в определении функции».

person Mark Rushakoff    schedule 23.09.2009
comment
Как упоминалось здесь, единственный способ преодолеть искажение __stdcall - это использование: #pragma comment(linker, "/EXPORT:SomeFunction=_SomeFunction@@@23mangledstuff#@@@@") - person Pierre; 17.06.2013
comment
ваша первая ссылка не работает, а вторая указывает на загрузку - person Simon Mourier; 19.12.2017

правильный ответ следующий:

extern "C" int MyFunc(int param);

и

int MyFunc(int param);

это два объявления, которые используют разное внутреннее именование, первое - в стиле C, второе - в стиле C ++.

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

оба этих стиля именования применяются при использовании __declspec (dllexport) одинаково.

если вы хотите опустить изменение имени экспортируемой подпрограммы, добавьте файл определения модуля в свой проект, введите его (в этом случае вам не требуется declspec dllexport):

LIBRARY mylib
EXPORTS
  MyFunc

при этом не будет явного оформления имени (примеры ниже).

_MyFunc (c style, __cdecl)
_MyFunc@4 (c style, __stdcall)
?MyFunc@@YAHH@Z (c++ style, __cdecl)
?MyFunc@@YGHH@Z (c++ style, __stdcall)
person sn0w    schedule 29.06.2013

Вы можете использовать переключатель компоновщика «-Wl, - kill-at», чтобы отключить изменение имени.

Например, в Code :: Blocks в настройках настраиваемого компоновщика добавьте: -Wl, - kill-at

person vga None    schedule 12.02.2014