Форум программистов, компьютерный форум 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++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
20.01.2014, 14:42     Как верно экспортить функцию? #2
А почему у тебя в коде нет параметров, а в дизасемблере целых два?
И где ты тут увидел что стек не удаляется?
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 14:50  [ТС]     Как верно экспортить функцию? #3
Не знаю откуда там аргументы взялись. Если бы стек удалился, то функция была бы чистым именем, без всяких доп символов. Мне ведь нужно применить для этого __cdecl, но не выходит.
Убежденный
Системный программист
 Аватар для Убежденный
14221 / 6236 / 988
Регистрация: 02.05.2013
Сообщений: 10,406
Завершенные тесты: 1
20.01.2014, 15:10     Как верно экспортить функцию? #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от pEntity Посмотреть сообщение
Если бы стек удалился, то функция была бы чистым именем, без всяких доп символов.
Вы путаете два понятия - соглашение о вызовах и декорацию имен.

Соглашение о вызовах (calling convention) определяет формат передачи аргументов в функцию.
Например, при _stdcall они передаются через стек, а затем удаляются оттуда вызываемой
функцией, в то время, как при _cdecl за очистку стека отвечает вызывающая сторона.

Декорация имен (name mangling) - "искажение" имен функций или данных во время экспорта.
Результат зависит от типа компоновки (extern "C" или extern "C++"), способа экспорта (DEF-файл
или директива __declspec(dllexport)) и типе соглашения о вызовах.

Чтобы в Visual C++ получить неискаженное имя, нужно или использовать DEF-файл, или
extern "C" + _cdecl.

Вот, набросал простенький примерчик:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
extern "C++"
__declspec(dllexport)
int _stdcall Dllexport_Cpp_Stdcall(int, int)
{
    return 0;
}
 
extern "C++"
__declspec(dllexport)
int _cdecl DllExport_Cpp_Cdecl(int, int)
{
    return 0;
}
 
extern "C"
__declspec(dllexport)
int _stdcall Dllexport_C_Stdcall(int, int)
{
    return 0;
}
 
extern "C"
__declspec(dllexport)
int _cdecl Dllexport_C_Cdecl(int, int)
{
    return 0;
}
 
extern "C++"
int _stdcall Deffile_Cpp_Stdcall(int, int)
{
    return 0;
}
 
extern "C++"
int _cdecl Deffile_Cpp_Cdecl(int, int)
{
    return 0;
}
 
extern "C"
int _stdcall Deffile_C_Stdcall(int, int)
{
    return 0;
}
 
extern "C"
int _cdecl Deffile_C_Cdecl(int, int)
{
    return 0;
}
Содержимое DEF-файла:
Код
LIBRARY "MyLibrary.dll"

EXPORTS
    Deffile_Cpp_Stdcall
    Deffile_Cpp_Cdecl
    Deffile_C_Stdcall
    Deffile_C_Cdecl
Вот какие имена получили экспортируемые функции:
Код
?DllExport_Cpp_Cdecl@@YAHHH@Z
?Dllexport_Cpp_Stdcall@@YGHHH@Z
Dllexport_C_Cdecl
_Dllexport_C_Stdcall@8
Deffile_C_Cdecl
Deffile_C_Stdcall
Deffile_Cpp_Cdecl
Deffile_Cpp_Stdcall
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 15:17  [ТС]     Как верно экспортить функцию? #5
Спасибо большое !!!
Avazart
 Аватар для Avazart
6910 / 5150 / 253
Регистрация: 10.12.2010
Сообщений: 22,657
Записей в блоге: 17
20.01.2014, 15:41     Как верно экспортить функцию? #6
Dynamic-Link Library: Теория + Практика
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 16:10  [ТС]     Как верно экспортить функцию? #7
C++
1
2
3
.text:1000BA40 ; int __stdcall SumFunc()
.text:1000BA40                 public ?SumFunc@@YGHXZ
.text:1000BA40 ?SumFunc@@YGHXZ proc near
C++
1
2
3
4
5
6
extern "C++"
__declspec(dllexport)
int _stdcall SumFunc()
{
    return 0;
}

/* ------------------------------ */

C++
1
2
3
.text:1000BA40 ; int __cdecl SumFunc()
.text:1000BA40                 public ?SumFunc@@YAHXZ
.text:1000BA40 ?SumFunc@@YAHXZ proc near
C++
1
2
3
4
5
6
extern "C++"
__declspec(dllexport)
int _cdecl SumFunc()
{
    return 0;
}

/* ------------------------------ */

C++
1
2
3
.text:1000BA40 ; int __stdcall SumFunc()
.text:1000BA40                 public _SumFunc@0
.text:1000BA40 _SumFunc@0      proc near
C++
1
2
3
4
5
6
extern "C"
__declspec(dllexport)
int _stdcall SumFunc()
{
    return 0;
}
/* ------------------------------ */

C++
1
2
3
.text:1000BA40 ; int __cdecl SumFunc()
.text:1000BA40                 public _SumFunc
.text:1000BA40 _SumFunc        proc near
C++
1
2
3
4
5
6
extern "C"
__declspec(dllexport)
int _cdecl SumFunc()
{
    return 0;
}

/* ------------------------------ */

Всегда искажение. Я что-то не понимаю или делаю не так ? Но мне нужно, чтоб экспортная функция не искажалась, а имела такое же имя как и функция сама.

Работаю в VS 2012.

Или без DEF файла ни как ?

Добавлено через 12 минут
Понятно почему теперь подчеркивает.

А где это в VS ?

Прототип функции Test(int); мог быть преобразован компилятором, например в ?Test@@YAKH@Z.
Естественно, такое декорирование нам вообще не по душе. Избавиться от него можно объявляя все экспортируемые функции с модификатором extern "C" - тогда компилятор не будет искажать имя функции.

Однако, как мы видим, нижние подчёркивание всё же добавилось.
Это один из нюансов среды C++ Builder. Однако, можно отучить его добавлять нижнее подчёркивание таким образом:
Project -> Options -> C++ Compiler -> Output -> Generate underscores on symbol names - перевести в состояние false.
И какая разница между __cdecl и _cdecl ?
Avazart
 Аватар для Avazart
6910 / 5150 / 253
Регистрация: 10.12.2010
Сообщений: 22,657
Записей в блоге: 17
20.01.2014, 16:17     Как верно экспортить функцию? #8
Цитата Сообщение от pEntity Посмотреть сообщение
Понятно почему теперь подчеркивает.
А где это в VS ?
То по большей части для С++Builder

Добавлено через 2 минуты
Цитата Сообщение от pEntity Посмотреть сообщение
Всегда искажение. Я что-то не понимаю или делаю не так ? Но мне нужно, чтоб экспортная функция не искажалась, а имела такое же имя как и функция сама.
Используй extern "C" не будет искажений.
Хотя стоп... как ты хочешь что бы ф-ция выглядела, и что ты имеешь ввиду под искажением?
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 17:49  [ТС]     Как верно экспортить функцию? #9
Вот как тут:

C++
1
2
3
4
5
6
extern "C"
__declspec(dllexport)
int _cdecl SumFunc()
{
    return 0;
}
Только, чтоб было без подчеркивания
C++
1
_
SumFunc

Просто чистое имя функции. И какую роль играет тут _cdecl ? Потому что, что с ним, что без него ничего не меняется, может он не нужен когда используется extern "C" ?
Avazart
 Аватар для Avazart
6910 / 5150 / 253
Регистрация: 10.12.2010
Сообщений: 22,657
Записей в блоге: 17
20.01.2014, 18:01     Как верно экспортить функцию? #10
Цитата Сообщение от pEntity Посмотреть сообщение
Только, чтоб было без подчеркивания
Какого подчекивания ?
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 18:03  [ТС]     Как верно экспортить функцию? #11
C++
1
2
3
.text:1000BA40 ; int __cdecl SumFunc()
.text:1000BA40                 public _SumFunc
.text:1000BA40 _SumFunc        proc near
_SumFunc
Avazart
 Аватар для Avazart
6910 / 5150 / 253
Регистрация: 10.12.2010
Сообщений: 22,657
Записей в блоге: 17
20.01.2014, 18:07     Как верно экспортить функцию? #12
Ну так в первой ф-ции нет искажения ?

Код
int __cdecl SumFunc()
Добавлено через 2 минуты
Цитата Сообщение от pEntity Посмотреть сообщение
И какую роль играет тут _cdecl ?
Соглашение вызова
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 18:11  [ТС]     Как верно экспортить функцию? #13
Ну это же не экспортная функция.
Avazart
 Аватар для Avazart
6910 / 5150 / 253
Регистрация: 10.12.2010
Сообщений: 22,657
Записей в блоге: 17
20.01.2014, 18:14     Как верно экспортить функцию? #14
Цитата Сообщение от pEntity Посмотреть сообщение
Ну это же не экспортная функция.
А какая импортная, заморская ?
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 18:20  [ТС]     Как верно экспортить функцию? #15
С __declspec(dllexport)
Avazart
 Аватар для Avazart
6910 / 5150 / 253
Регистрация: 10.12.2010
Сообщений: 22,657
Записей в блоге: 17
20.01.2014, 18:26     Как верно экспортить функцию? #16
Цитата Сообщение от pEntity Посмотреть сообщение
С __declspec(dllexport)
Словарный запас закончился ?
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 18:37  [ТС]     Как верно экспортить функцию? #17
Чего чего? Если нет ключевого слова __declspec(dllexport), значит это не экспортная функция.

C++
1
int __cdecl SumFunc()
Это экспортная функция ?
Avazart
 Аватар для Avazart
6910 / 5150 / 253
Регистрация: 10.12.2010
Сообщений: 22,657
Записей в блоге: 17
20.01.2014, 18:42     Как верно экспортить функцию? #18
А как ты ее увидал если она не экспортная ?

Код
.text:10001000 ; void __cdecl SumFunc(void *__formal, void *__formal)
.text:10001000                 public ?SumFunc@@YAXXZ
.text:10001000 ?SumFunc@@YAXXZ proc near
Что это откуда это ты взял ?
pEntity
10 / 5 / 1
Регистрация: 12.12.2012
Сообщений: 371
20.01.2014, 18:50  [ТС]     Как верно экспортить функцию? #19
Декомпил с помощью IDA

C++
1
2
3
4
extern "C" __declspec(dllexport) void _cdecl AlertMessage( ALERT_TYPE atype, char *szFmt, ... )
{
 
}
Миниатюры
Как верно экспортить функцию?  
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.01.2014, 18:55     Как верно экспортить функцию?
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
Avazart
 Аватар для Avazart
6910 / 5150 / 253
Регистрация: 10.12.2010
Сообщений: 22,657
Записей в блоге: 17
20.01.2014, 18:55     Как верно экспортить функцию? #20
Цитата Сообщение от pEntity Посмотреть сообщение
Декомпил с помощью IDA
И чЁ, наХ это было делать ? Откуда уверенность что IDA отображает правильно имена?

Смотри PE Exploer-ом
Yandex
Объявления
20.01.2014, 18:55     Как верно экспортить функцию?
Ответ Создать тему
Опции темы

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