Есть ли способ подавить искажение имени c ++?

У меня есть DLL, написанная на C ++, и я хочу подавить искажение имени для нескольких экспортируемых методов. Эти методы являются глобальными и не являются членами какого-либо класса. Есть ли способ добиться этого?

Кстати: я использую VS2008.


person Ohad Horesh    schedule 23.05.2009    source источник
comment
Я думаю, что это дублирование: stackoverflow.com / questions / 524633 /   -  person Johannes Schaub - litb    schedule 24.05.2009
comment
ИМО, не совсем дуплик: здесь мы говорим об экспортируемых функциях DLL, которые вносят в игру совершенно другое решение.   -  person Serge Wautier    schedule 25.05.2009


Ответы (3)


bradtgmurray прав, но для компиляторов Visual C ++ вам все равно нужно явно экспортировать свою функцию. Но использование файла .DEF, предложенного Сержем - appTranslator, - неправильный способ сделать это.

Каков универсальный способ экспорта символов в Visual C ++?

Использование инструкции declspec (dllexport / dllimport), которая работает как для кода C, так и для кода C ++, независимо от того, декорирована она или нет (тогда как .DEF ограничен C, если вы не хотите украсить свой код вручную).

Итак, правильный способ экспорта недекорированных функций в Visual C ++ - это комбинировать идиому экспорта C, как отвечает bradtgmurray, и ключевое слово dllimport / dllexport.

Пример ?

В качестве примера я создал на Visual C ++ пустой проект DLL и написал две функции: одну назвали CPP, потому что она была оформлена, а другую - C, потому что это не так. Код такой:

// Exported header
#ifdef MY_DLL_EXPORTS
#define MY_DLL_API __declspec(dllexport)
#else
#define MY_DLL_API __declspec(dllimport)
#endif

// Decorated function export : ?myCppFunction@@YAHF@Z
MY_DLL_API int myCppFunction(short v) ;

// Undecorated function export : myCFunction
extern "C"
{
MY_DLL_API int myCFunction(short v) ;
} ;

Думаю, вы уже знаете, но для полноты картины макрос MY_DLL_API должен быть определен в make-файле DLL (то есть VCPROJ), но не пользователями DLL.

Код на C ++ легко написать, но для полноты картины я напишу его ниже:

// Decorated function code
MY_DLL_API int myCppFunction(short v)
{
   return 42 * v ;
}

extern "C"
{

// Undecorated function code
MY_DLL_API int myCFunction(short v)
{
   return 42 * v ;
}

} ;
person paercebal    schedule 26.05.2009
comment
Спасибо за отличный ответ ... именно то, что мне нужно. - person Polaris878; 22.09.2009
comment
Я создаю класс в явной Dll. Вызов конструктора для этого класса генерирует ошибку Неразрешенный внешний символ .... Я предполагаю, что это связано с искажением имени. Напишите, пожалуйста, как избежать этой проблемы. Файл DEF или extern C здесь не помогает. - person null; 20.03.2013
comment
@ajay: Я не могу помочь вам в комментариях. Что вы могли сделать, так это использовать Visual Studio для создания библиотеки DLL с примерами символов, чтобы увидеть, как это делается. Если вы все еще застряли, вам следует опубликовать (ограниченную версию) свой код в StackOverflow (или CodeReview?), Включая как код DLL (заголовок, источник), так и связанный с ним код EXE (источник), и сообщение об ошибке. Возможно, ваша ошибка возникла из-за неправильного вызова перегрузки конструктора: есть ли ошибка, если вы попытаетесь вызвать тот же конструктор изнутри DLL? Если да, то вам нужно объявить / определить правильный конструктор. - person paercebal; 21.03.2013

Заключите определения функций в extern "C" {}

extern "C" {
    void foo() {}
}

См. http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

person bradtgmurray    schedule 23.05.2009
comment
Вам нужно, чтобы и объявление, и определение были extern Ced, верно? - person leander; 26.05.2009
comment
@leander Нет, достаточно просто декларации; до тех пор, пока объявление включено в точку определения и подписи точно совпадают, C-сущность будет применена к определению автоматически. Вы можете установить его на обоих, и если, например, параметры не совпадают в точности, вы получите ошибку (C2733 в VS) вместо того, чтобы автоматически экспортировать неправильную версию. - person Tim Sylvester; 11.10.2017

Вы можете избежать всех манипуляций (C ++, cdecl, stdcall, ...) для экспортируемых функций, используя файл .def с разделом EXPORTS. Просто создайте файл MyDll.def и добавьте его в свой проект:

LIBRARY "MyDLL"
EXPORTS
  Foo
  Bar

На самом деле, скорее всего, мастер уже создал для вас файл def. Вам достаточно заполнить раздел ЭКСПОРТ.

person Serge Wautier    schedule 25.05.2009