Форум программистов, компьютерный форум CyberForum.ru

Как верно экспортить функцию? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.93
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 14:12     Как верно экспортить функцию? #1
C++
1
2
3
4
5
6
7
#define _DECLARATOR_ __declspec(dllexport)
 
 
_DECLARATOR_ void __cdecl SumFunc()
{
    return;
}
C++
1
2
3
.text:10001000 ; void __cdecl SumFunc(void *__formal, void *__formal)
.text:10001000                 public ?SumFunc@@YAXXZ
.text:10001000 ?SumFunc@@YAXXZ proc near


__cdecl должно было удалить лишнии символы в стеке О_о

______________________________________________________________________________

C++
1
2
3
4
extern "C" void __declspec(dllexport) SumFunc()
{
    return;
}
C++
1
2
3
.text:10001000 ; void __cdecl SumFunc(void *__formal, void *__formal)
.text:10001000                 public _SumFunc
.text:10001000 _SumFunc        proc near
В этом варианте с __cdecl так же ничего не измениться.

________________________________________________________

C++
1
2
3
4
void __declspec(dllexport) SumFunc()
{
    return;
}
C++
1
2
3
.text:10001000 ; void __cdecl SumFunc(void *__formal, void *__formal)
.text:10001000                 public ?SumFunc@@YAXXZ
.text:10001000 ?SumFunc@@YAXXZ proc near

Так как же верно экспортить? Для чего extern "C" ? __declspec(dllexport) пихать перед void или после ? Как сделать, чтоб имя было без любых доп символов ?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.01.2014, 14:12     Как верно экспортить функцию?
Посмотрите здесь:

Как передать указатель на функцию в функцию C++
как мне функцию одного класса в функцию базового вставить C++
C++ Задача логические функции (составить функцию, которая определяет верно ли что сумма цифр числа четное число)
не могу разобраться как написать функцию сортировки и исправить функцию добавления в стек C++
Перегрузка операций (Создать класс вещественных чисел (double); определить оператор +, как функцию-элемент и – как дружественную функцию) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 18:57  [ТС]     Как верно экспортить функцию? #21
Я тебя не понимаю. То есть ты утверждаешь, что это экспортная функция ? int __cdecl SumFunc()

Я спрашиваю просто как сделать, чтоб ни какие символы не добавлялись.

Объясни, если у нас какие-то недопонимания.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,607
Записей в блоге: 17
20.01.2014, 19:00     Как верно экспортить функцию? #22
Добавлено через 42 секунды
Цитата Сообщение от pEntity Посмотреть сообщение
Я спрашиваю просто как сделать, чтоб ни какие символы не добавлялись.
Объясни, если у нас какие-то недопонимания.
Выкинуть очки ... что не понятно не смотри IDA

Для заметки в нагрузку Создание в среде Borland C++ Builder dll, совместимой с Visual C++

от туда :
В таблице 1 приведены возможные варианты наименований для экспортируемой функции MyFunction, объявленной следующим образом:

extern ”C” void __declspec(dllexport) <calling convention> MyFunction(int Param);

в зависимости от соглашения о вызове (<calling convention>) и компилятора.
Соглашение о вызове VC++ C++ Builder
__stdcall _MyFunction@4 MyFunction
__cdecl MyFunction _MyFunction
Таблица 1. Наименования функций в зависимости от соглашения о вызове и компилятора.
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 19:06  [ТС]     Как верно экспортить функцию? #23
IDA не обманывает. Символ лишний есть. Даже GetProcAdress ловит с лишним символом только функцию ( _SumFunc), что-то скорей всего с настройками VS.
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,607
Записей в блоге: 17
20.01.2014, 19:07     Как верно экспортить функцию? #24
Выложи DLL, а лучше весь проект...
Tulosba
20.01.2014, 21:34
  #25

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
Для заметки в нагрузку Создание в среде Borland C++ Builder dll, совместимой с Visual C++
Делал я как-то "совместимую" dll, насколько помню, функции все находились, аргументы передавались, однако периодически всё крешилось. Помогла только пересборка под студией (без каких-либо изменений в коде).

Убежденный
Системный программист
 Аватар для Убежденный
14200 / 6215 / 986
Регистрация: 02.05.2013
Сообщений: 10,362
Завершенные тесты: 1
20.01.2014, 22:40     Как верно экспортить функцию? #26
Цитата Сообщение от pEntity Посмотреть сообщение
IDA не обманывает. Символ лишний есть. Даже GetProcAdress ловит с лишним символом только функцию ( _SumFunc), что-то скорей всего с настройками VS.
Проверил ради интереса на Visual C++ 2013:
Пустой Win32-проект dll, в нем следующая функция (не считая DllMain):
C++
1
2
3
4
5
6
extern "C"
__declspec(dllexport)
int SomeFunc(int, int)
{
    return 123;
}
Скомпилировал, запустил dumpbin с параметрами /ALL и /RAWDATA:NONE.
Вот фрагмент вывода:
Код
  Section contains the following exports for mylib.dll

    00000000 characteristics
    52DD5DA6 time date stamp Mon Jan 20 09:32:22 2014
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001000 SomeFunc
Как видим, никаких подчеркиваний.
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 23:27  [ТС]     Как верно экспортить функцию? #27
Я тоже на 13 проверил уже. Все работает, а на 12 подчеркивает.
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,607
Записей в блоге: 17
21.01.2014, 02:06     Как верно экспортить функцию? #28
Цитата Сообщение от Tulosba Посмотреть сообщение
Делал я как-то "совместимую" dll, насколько помню, функции все находились, аргументы передавались, однако периодически всё крешилось. Помогла только пересборка под студией (без каких-либо изменений в коде).
Ну переносимый код вероятно лучше нежели "переносимая DLL".

Добавлено через 1 минуту
Цитата Сообщение от pEntity Посмотреть сообщение
Я тоже на 13 проверил уже. Все работает, а на 12 подчеркивает.
Странно я думал это 13 мистическое число ...

Добавлено через 2 минуты
Цитата Сообщение от Убежденный Посмотреть сообщение
Чтобы в Visual C++ получить неискаженное имя, нужно или использовать DEF-файл, или
extern "C" + _cdecl.
Насколько я понимаю DEF - файл лишь вводит псевдоним в lib файл для экспорта DLL.
HighPredator
 Аватар для HighPredator
5351 / 1734 / 320
Регистрация: 10.12.2010
Сообщений: 5,120
Записей в блоге: 3
21.01.2014, 16:03     Как верно экспортить функцию? #29
Цитата Сообщение от pEntity Посмотреть сообщение
Я тоже на 13 проверил уже. Все работает, а на 12 подчеркивает.
Стандарта спецификации по манглированию имен функций не существует (по крайней мере точно у МС), поэтому имена могут меняться в зависимости от версии компилятора. Во-вторых, существует распространенное заблуждение, жертвой которого потенциально можно стать. dllexport будет искажать имя функции в соответствии с ее описанием. То есть С++ функция будет иметь искажение характерное для С++ функции, а С для С соответственно. Использование extern "C" задает принудительно искажение, характерное для С функций, а не "отключает" его совсем. А вот чтобы экспортировать функцию действительно без искажений, нужно использовать DEF файл. Или использовать директивы компоновщика для каждой функции (нужно для того, чтобы функция с неискаженным именем имела ту же точку входа, что и искаженная).
Теперь по поводу подчеркивания. Это характерое Си искажение. Что и не удивительно, раз было указано extern C.
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,607
Записей в блоге: 17
21.01.2014, 16:07     Как верно экспортить функцию? #30
Цитата Сообщение от HighPredator Посмотреть сообщение
характерное для С функций
Когда это Си- ф-ции искажались декорировались ?
Причиной необходимости искажений в С++ насколько я помню это необходимость разрешения перегрузки ф-ций, которой нет в Си.

Цитата Сообщение от HighPredator Посмотреть сообщение
А вот чтобы экспортировать функцию действительно без искажений, нужно использовать DEF файл.
А если грузим динамически ?
HighPredator
 Аватар для HighPredator
5351 / 1734 / 320
Регистрация: 10.12.2010
Сообщений: 5,120
Записей в блоге: 3
21.01.2014, 16:18     Как верно экспортить функцию? #31
Цитата Сообщение от Avazart Посмотреть сообщение
Когда это Си- ф-ции искажались
В моем понимании всегда. Они все имеют нижнее подчеркивание в начале. Так записано у меня по крайней мере. К тому же теория говорит о том, что соглашение Си функций cdecl дает функцию вида _MyFunct, stdcall -- _MyFunct@4, fastcall -- @MyFunct@4. Число с потолка. Поправьте где не прав.

Добавлено через 6 минут
Цитата Сообщение от Avazart Посмотреть сообщение
А если грузим динамически ?
Так логика от этого не меняется. GetProcAddr все равно требует точность в имени функции.
Убежденный
Системный программист
 Аватар для Убежденный
14200 / 6215 / 986
Регистрация: 02.05.2013
Сообщений: 10,362
Завершенные тесты: 1
21.01.2014, 16:52     Как верно экспортить функцию? #32
Цитата Сообщение от pEntity Посмотреть сообщение
Я тоже на 13 проверил уже. Все работает, а на 12 подчеркивает.
Проверил на VS2012 Professional:
Вывод утилиты dumpbin:
Код
Section contains the following exports for mylib2.dll

    00000000 characteristics
    52DE5E6C time date stamp Tue Jan 21 03:47:56 2014
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001000 SomeFunc2
Никакого подчеркивания снова нет.
Функция определена так:
C++
1
2
3
4
5
6
7
8
extern "C"
__declspec(dllexport)
int
_cdecl
SomeFunc2(int, int)
{
    return 456;
}
HighPredator
 Аватар для HighPredator
5351 / 1734 / 320
Регистрация: 10.12.2010
Сообщений: 5,120
Записей в блоге: 3
21.01.2014, 17:42     Как верно экспортить функцию? #33
Контрпример (см. скрин). Я ранее написал, что все зависит от компилятора. Какой-то подавит, какой-то нет. Теоретических предпосылок к гарантированному подавлению нет. Полное подавление гарантируется деф файлом.
Миниатюры
Как верно экспортить функцию?  
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,607
Записей в блоге: 17
21.01.2014, 17:50     Как верно экспортить функцию? #34
HighPredator, О_у это же С++Builder это чисто его прибабаха добавлять подчеркивание при чем если не ошибаюсь
эту опцию добавления можно убрать в настройках среды.
Кроме того _ вряд ли можно считать декорированием.

Мы же ту вроде говорим про VC++ и в случае ТС с его соглашением вызова не должно быть подчеркиваний и вообще искажений.

Добавлено через 3 минуты
Цитата Сообщение от HighPredator Посмотреть сообщение
Полное подавление гарантируется деф файлом.
Блин, еще раз - def ничего не подавляет в DLL просто добавляет псевдоним.
HighPredator
 Аватар для HighPredator
5351 / 1734 / 320
Регистрация: 10.12.2010
Сообщений: 5,120
Записей в блоге: 3
21.01.2014, 17:59     Как верно экспортить функцию? #35
Честно уже устал повторять...
Цитата Сообщение от Avazart Посмотреть сообщение
с его соглашением вызова не должно быть подчеркиваний и вообще искажений
there is no standard specification for name decoration, the name of an exported function might change between compiler versions
Ссыль. http://msdn.microsoft.com/en-us/libr...(v=vs.80).aspx

Добавлено через 4 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
Блин, еще раз - def ничего не подавляет в DLL просто добавляет псевдоним.
Да какая разница каким словом я это обозвал? Суть то одна.
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,607
Записей в блоге: 17
21.01.2014, 18:09     Как верно экспортить функцию? #36
Цитата Сообщение от HighPredator Посмотреть сообщение
Где ты там видел про подчеркивание и про Си ?

Добавлено через 3 минуты
This convenience is most apparent when trying to export decorated C++ function names. Because there is no standard specification for name decoration, the name of an exported function might change between compiler versions. If you use __declspec(dllexport), recompiling the DLL and dependent .exe files is necessary only to account for any naming convention changes.
Ключевое слово C++ function, а не то что может зависеть от компилятора.

Добавлено через 1 минуту
Шагаем далее http://msdn.microsoft.com/en-US/libr...=vs.80%29.aspx

If you have functions in a DLL written in C++ that you want to access from a C-language module, you should declare these functions with C linkage instead of C++ linkage. Unless otherwise specified, the C++ compiler uses C++ type-safe naming (also known as name decoration) and C++ calling conventions, which can be difficult to call from C.

To specify C linkage, specify extern "C" for your function declarations. For example:

extern "C" __declspec( dllexport ) int MyFunc(long parm1);
HighPredator
 Аватар для HighPredator
5351 / 1734 / 320
Регистрация: 10.12.2010
Сообщений: 5,120
Записей в блоге: 3
21.01.2014, 18:17     Как верно экспортить функцию? #37
Цитата Сообщение от Avazart Посмотреть сообщение
это же С++Builder это чисто его прибабаха добавлять подчеркивание
Не для функций. http://www.agner.org/optimize/calling_conventions.pdf Раздел 8.2 Borland name mangling.

Добавлено через 4 минуты
dllexport of a function exposes the function with its decorated name. For C++ functions, this includes name mangling. For C functions or functions that are declared as extern "C", this includes platform-specific decoration that's based on the calling convention. If you don't want name decoration, use a .def file (EXPORTS keyword)
http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx

Добавлено через 3 минуты

Не по теме:

Avazart, можно было сразу ссылку спросить, а не троллить меня две страницы. Некрасиво.

Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,607
Записей в блоге: 17
21.01.2014, 18:17     Как верно экспортить функцию? #38
For C functions or functions that are declared as extern "C", this includes platform-specific decoration that's based on the calling convention.
Речь про VC++, c эти соглашением что у ТС подчеркивания не должно быть ...

Что касается def файла, то с генерённый на его основе lib тоже не будет зависеть от компилятора.
Убежденный
Системный программист
 Аватар для Убежденный
14200 / 6215 / 986
Регистрация: 02.05.2013
Сообщений: 10,362
Завершенные тесты: 1
21.01.2014, 18:28     Как верно экспортить функцию? #39
Цитата Сообщение от HighPredator Посмотреть сообщение
Контрпример (см. скрин). Я ранее написал, что все зависит от компилятора. Какой-то подавит, какой-то нет. Теоретических предпосылок к гарантированному подавлению нет.
Совершенно верно. name mangling, как и вообще двоичный интерфейс C++ - штука
не стандартизированная и может отличаться даже в рамках одного компилятора.
Поэтому я еще на первой странице написал:
Чтобы в Visual C++ получить неискаженное имя, нужно или использовать DEF-файл, или
extern "C" + _cdecl.
На счет других компиляторов - не знаю, с ними особо не работал.
У М. Уилсона в его книге "Imperfect C++" этот вопрос, кстати, дотошно разбирался,
вплоть до приведения "таблиц совместимости".
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.01.2014, 18:30     Как верно экспортить функцию?
Еще ссылки по теме:

Как верно перевести формулу на язык c++? C++
C++ Как верно узнать размер указателя ?
Как правильно вызвать функцию с указателем на другую функцию как параметр C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
HighPredator
 Аватар для HighPredator
5351 / 1734 / 320
Регистрация: 10.12.2010
Сообщений: 5,120
Записей в блоге: 3
21.01.2014, 18:30     Как верно экспортить функцию? #40
Цитата Сообщение от Avazart Посмотреть сообщение
не должно быть ...
Это лирика.
Цитата Сообщение от Avazart Посмотреть сообщение
Что касается def файла, то с генерённый на его основе lib тоже не будет зависеть от компилятора.
Этот файл вообще нужен только на этапе компоновки. Компилятор тут никаким боком.
Yandex
Объявления
21.01.2014, 18:30     Как верно экспортить функцию?
Ответ Создать тему
Опции темы

Текущее время: 17:45. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru