327 / 252 / 58
Регистрация: 12.12.2012
Сообщений: 2,048
1

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

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

Author24 — интернет-сервис помощи студентам
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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.01.2014, 14:12
Ответы с готовыми решениями:

Как синтактически верно составить пользовательскую функцию?
Привет. Прошу не ругайте сильно... Подскажите, в чем ошибка с моей стороны? отладчик ругается...

как сделать чтобы на label1 выходило значение верно или не верно?
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { int...

Как мне сделать чтобы на label1 выходило значение верно или не верно?
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { int...

Написать функцию,которая определяет, верно ли что последняя цифры в числе 5
Написать функцию,которая определяет, верно ли что последняя цифры в числе 5

45
327 / 252 / 58
Регистрация: 12.12.2012
Сообщений: 2,048
20.01.2014, 18:57  [ТС] 21
Author24 — интернет-сервис помощи студентам
Я тебя не понимаю. То есть ты утверждаешь, что это экспортная функция ? int __cdecl SumFunc()

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

Объясни, если у нас какие-то недопонимания.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
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. Наименования функций в зависимости от соглашения о вызове и компилятора.
0
327 / 252 / 58
Регистрация: 12.12.2012
Сообщений: 2,048
20.01.2014, 19:06  [ТС] 23
IDA не обманывает. Символ лишний есть. Даже GetProcAdress ловит с лишним символом только функцию ( _SumFunc), что-то скорей всего с настройками VS.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
20.01.2014, 19:07 24
Выложи DLL, а лучше весь проект...
0
Tulosba
20.01.2014, 21:34
  #25

Не по теме:

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

0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 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
Как видим, никаких подчеркиваний.
1
327 / 252 / 58
Регистрация: 12.12.2012
Сообщений: 2,048
20.01.2014, 23:27  [ТС] 27
Я тоже на 13 проверил уже. Все работает, а на 12 подчеркивает.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
21.01.2014, 02:06 28
Цитата Сообщение от Tulosba Посмотреть сообщение
Делал я как-то "совместимую" dll, насколько помню, функции все находились, аргументы передавались, однако периодически всё крешилось. Помогла только пересборка под студией (без каких-либо изменений в коде).
Ну переносимый код вероятно лучше нежели "переносимая DLL".

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

Добавлено через 2 минуты
Цитата Сообщение от Убежденный Посмотреть сообщение
Чтобы в Visual C++ получить неискаженное имя, нужно или использовать DEF-файл, или
extern "C" + _cdecl.
Насколько я понимаю DEF - файл лишь вводит псевдоним в lib файл для экспорта DLL.
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
21.01.2014, 16:03 29
Цитата Сообщение от pEntity Посмотреть сообщение
Я тоже на 13 проверил уже. Все работает, а на 12 подчеркивает.
Стандарта спецификации по манглированию имен функций не существует (по крайней мере точно у МС), поэтому имена могут меняться в зависимости от версии компилятора. Во-вторых, существует распространенное заблуждение, жертвой которого потенциально можно стать. dllexport будет искажать имя функции в соответствии с ее описанием. То есть С++ функция будет иметь искажение характерное для С++ функции, а С для С соответственно. Использование extern "C" задает принудительно искажение, характерное для С функций, а не "отключает" его совсем. А вот чтобы экспортировать функцию действительно без искажений, нужно использовать DEF файл. Или использовать директивы компоновщика для каждой функции (нужно для того, чтобы функция с неискаженным именем имела ту же точку входа, что и искаженная).
Теперь по поводу подчеркивания. Это характерое Си искажение. Что и не удивительно, раз было указано extern C.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
21.01.2014, 16:07 30
Цитата Сообщение от HighPredator Посмотреть сообщение
характерное для С функций
Когда это Си- ф-ции искажались декорировались ?
Причиной необходимости искажений в С++ насколько я помню это необходимость разрешения перегрузки ф-ций, которой нет в Си.

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

Добавлено через 6 минут
Цитата Сообщение от Avazart Посмотреть сообщение
А если грузим динамически ?
Так логика от этого не меняется. GetProcAddr все равно требует точность в имени функции.
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 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;
}
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
21.01.2014, 17:42 33
Контрпример (см. скрин). Я ранее написал, что все зависит от компилятора. Какой-то подавит, какой-то нет. Теоретических предпосылок к гарантированному подавлению нет. Полное подавление гарантируется деф файлом.
Миниатюры
Как верно экспортить функцию?  
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
21.01.2014, 17:50 34
HighPredator, О_у это же С++Builder это чисто его прибабаха добавлять подчеркивание при чем если не ошибаюсь
эту опцию добавления можно убрать в настройках среды.
Кроме того _ вряд ли можно считать декорированием.

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

Добавлено через 3 минуты
Цитата Сообщение от HighPredator Посмотреть сообщение
Полное подавление гарантируется деф файлом.
Блин, еще раз - def ничего не подавляет в DLL просто добавляет псевдоним.
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 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-u... s.80).aspx

Добавлено через 4 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
Блин, еще раз - def ничего не подавляет в DLL просто добавляет псевдоним.
Да какая разница каким словом я это обозвал? Суть то одна.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
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-U... 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);
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
21.01.2014, 18:17 37
Цитата Сообщение от Avazart Посмотреть сообщение
это же С++Builder это чисто его прибабаха добавлять подчеркивание
Не для функций. http://www.agner.org/optimize/... ntions.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-u... sfaz2.aspx

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

Не по теме:

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

0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
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 тоже не будет зависеть от компилятора.
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
21.01.2014, 18:28 39
Цитата Сообщение от HighPredator Посмотреть сообщение
Контрпример (см. скрин). Я ранее написал, что все зависит от компилятора. Какой-то подавит, какой-то нет. Теоретических предпосылок к гарантированному подавлению нет.
Совершенно верно. name mangling, как и вообще двоичный интерфейс C++ - штука
не стандартизированная и может отличаться даже в рамках одного компилятора.
Поэтому я еще на первой странице написал:
Чтобы в Visual C++ получить неискаженное имя, нужно или использовать DEF-файл, или
extern "C" + _cdecl.
На счет других компиляторов - не знаю, с ними особо не работал.
У М. Уилсона в его книге "Imperfect C++" этот вопрос, кстати, дотошно разбирался,
вплоть до приведения "таблиц совместимости".
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
21.01.2014, 18:30 40
Цитата Сообщение от Avazart Посмотреть сообщение
не должно быть ...
Это лирика.
Цитата Сообщение от Avazart Посмотреть сообщение
Что касается def файла, то с генерённый на его основе lib тоже не будет зависеть от компилятора.
Этот файл вообще нужен только на этапе компоновки. Компилятор тут никаким боком.
0
21.01.2014, 18:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.01.2014, 18:30
Помогаю со студенческими работами здесь

Составить функцию, которая определяет, верно ли, что в заданном числе все цифры стоят по возрастанию
Составить функцию, которая определяет, верно ли, что в заданном числе все цифры стоят по...

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

ДМ. Логически доказать равенство; и что вложение верно, а обратное не верно; построить формулу
Здравствуйте, я понимаю, что тут не любители отвечать очередному Васе Пупкину. Но всё-же, буду...

Даны три числа a,b,c . Выяснить, верно ли, что a<b<c. Ответ получить в текстовой форме: верно или неверно
Даны три числа a,b,c . Выяснить, верно ли, что a&lt;b&lt;c. Ответ получить в текстовой форме: верно или...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru