Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
1

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

20.01.2014, 14:12. Просмотров 2312. Ответов 45
Метки нет (Все метки)

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 или после ? Как сделать, чтоб имя было без любых доп символов ?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.01.2014, 14:12
Ответы с готовыми решениями:

Задача логические функции (составить функцию, которая определяет верно ли что сумма цифр числа четное число)
Помогите нужно составить функцию, которая определяет верно ли что сумма цифр...

Перегрузка операций (Создать класс вещественных чисел (double); определить оператор +, как функцию-элемент и – как дружественную функцию)
помогите решить пожалуйста Задание 2. Бинарная операция Создать класс...

Как правильно вызвать функцию с указателем на другую функцию как параметр
Вот вариант: double f(double x) { ... } double k(double...

Как верно узнать размер указателя ?
СBaseTest* pTest = { new СBaseTest, new СOther }; Нужно узнать размер pTest

Как верно перевести формулу на язык c++?
Приветствую! Столкнулся с такой задачей в университете на 1 курсе... нужно...

45
castaway
Эксперт С++
4934 / 3039 / 455
Регистрация: 10.11.2010
Сообщений: 11,119
Записей в блоге: 10
Завершенные тесты: 1
20.01.2014, 14:42 2
А почему у тебя в коде нет параметров, а в дизасемблере целых два?
И где ты тут увидел что стек не удаляется?
0
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
20.01.2014, 14:50  [ТС] 3
Не знаю откуда там аргументы взялись. Если бы стек удалился, то функция была бы чистым именем, без всяких доп символов. Мне ведь нужно применить для этого __cdecl, но не выходит.
0
Убежденный
Ушел с форума
Эксперт С++
16126 / 7273 / 1181
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 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
6
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
20.01.2014, 15:17  [ТС] 5
Спасибо большое !!!
0
Avazart
Эксперт С++
7737 / 5647 / 550
Регистрация: 10.12.2010
Сообщений: 25,495
Записей в блоге: 17
20.01.2014, 15:41 6
Dynamic-Link Library: Теория + Практика
2
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
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 ?
0
Avazart
Эксперт С++
7737 / 5647 / 550
Регистрация: 10.12.2010
Сообщений: 25,495
Записей в блоге: 17
20.01.2014, 16:17 8
Цитата Сообщение от pEntity Посмотреть сообщение
Понятно почему теперь подчеркивает.
А где это в VS ?
То по большей части для С++Builder

Добавлено через 2 минуты
Цитата Сообщение от pEntity Посмотреть сообщение
Всегда искажение. Я что-то не понимаю или делаю не так ? Но мне нужно, чтоб экспортная функция не искажалась, а имела такое же имя как и функция сама.
Используй extern "C" не будет искажений.
Хотя стоп... как ты хочешь что бы ф-ция выглядела, и что ты имеешь ввиду под искажением?
0
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
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" ?
0
Avazart
Эксперт С++
7737 / 5647 / 550
Регистрация: 10.12.2010
Сообщений: 25,495
Записей в блоге: 17
20.01.2014, 18:01 10
Цитата Сообщение от pEntity Посмотреть сообщение
Только, чтоб было без подчеркивания
Какого подчекивания ?
0
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
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
0
Avazart
Эксперт С++
7737 / 5647 / 550
Регистрация: 10.12.2010
Сообщений: 25,495
Записей в блоге: 17
20.01.2014, 18:07 12
Ну так в первой ф-ции нет искажения ?

Код
int __cdecl SumFunc()
Добавлено через 2 минуты
Цитата Сообщение от pEntity Посмотреть сообщение
И какую роль играет тут _cdecl ?
Соглашение вызова
0
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
20.01.2014, 18:11  [ТС] 13
Ну это же не экспортная функция.
0
Avazart
Эксперт С++
7737 / 5647 / 550
Регистрация: 10.12.2010
Сообщений: 25,495
Записей в блоге: 17
20.01.2014, 18:14 14
Цитата Сообщение от pEntity Посмотреть сообщение
Ну это же не экспортная функция.
А какая импортная, заморская ?
0
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
20.01.2014, 18:20  [ТС] 15
С __declspec(dllexport)
0
Avazart
Эксперт С++
7737 / 5647 / 550
Регистрация: 10.12.2010
Сообщений: 25,495
Записей в блоге: 17
20.01.2014, 18:26 16
Цитата Сообщение от pEntity Посмотреть сообщение
С __declspec(dllexport)
Словарный запас закончился ?
0
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
20.01.2014, 18:37  [ТС] 17
Чего чего? Если нет ключевого слова __declspec(dllexport), значит это не экспортная функция.

C++
1
int __cdecl SumFunc()
Это экспортная функция ?
0
Avazart
Эксперт С++
7737 / 5647 / 550
Регистрация: 10.12.2010
Сообщений: 25,495
Записей в блоге: 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
Что это откуда это ты взял ?
0
pEntity
92 / 109 / 24
Регистрация: 12.12.2012
Сообщений: 1,200
20.01.2014, 18:50  [ТС] 19
Декомпил с помощью IDA

C++
1
2
3
4
extern "C" __declspec(dllexport) void _cdecl AlertMessage( ALERT_TYPE atype, char *szFmt, ... )
{
 
}
0
Миниатюры
Как верно экспортить функцию?  
Avazart
Эксперт С++
7737 / 5647 / 550
Регистрация: 10.12.2010
Сообщений: 25,495
Записей в блоге: 17
20.01.2014, 18:55 20
Цитата Сообщение от pEntity Посмотреть сообщение
Декомпил с помощью IDA
И чЁ, наХ это было делать ? Откуда уверенность что IDA отображает правильно имена?

Смотри PE Exploer-ом
0
20.01.2014, 18:55
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.01.2014, 18:55

Как сделать, чтобы 2 одинаковых перегруженных оператора выполнялись верно
Всем привет! Столкнулся с такой ситуацией, что мне понадобилось использовать 2...

как мне функцию одного класса в функцию базового вставить
как мне функцию одного класса в функцию базового вставить??чет не хера не...

не могу разобраться как написать функцию сортировки и исправить функцию добавления в стек
#include <iostream> #include<Windows.h> using namespace std; struct NE{...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru