Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 08.07.06 10:46
Оценка:
Простите за глупый вопрос, ситуация такая:

нужно в VS2005 импортировать из dll функцию stdcall, однако при запуске программы он вместо функции Func ищет функцию, типа ?Func@XXZZYYA.
Использование директивы extern "C" не проходит, так как вызвать нужно именно stdcall

09.07.06 05:15: Перенесено модератором из 'C/C++' — Павел Кузнецов
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re: Как импортировать функцию stdcall
От: _nn_  
Дата: 08.07.06 10:51
Оценка:
Здравствуйте, Ракопаукодав, Вы писали:

Р>Простите за глупый вопрос, ситуация такая:


Р>нужно в VS2005 импортировать из dll функцию stdcall, однако при запуске программы он вместо функции Func ищет функцию, типа ?Func@XXZZYYA.

Р>Использование директивы extern "C" не проходит, так как вызвать нужно именно stdcall

Нужно, чтобы при определении и при использовании сигнатуры совпадали.

// В Dll
extern "C" __declspec(dllexport) void __stdcall Func()
{
}

// В Exe
extern "C" __declspec(dllimport) void __stdcall Func();
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 08.07.06 10:58
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, Ракопаукодав, Вы писали:


Р>>Простите за глупый вопрос, ситуация такая:


Р>>нужно в VS2005 импортировать из dll функцию stdcall, однако при запуске программы он вместо функции Func ищет функцию, типа ?Func@XXZZYYA.

Р>>Использование директивы extern "C" не проходит, так как вызвать нужно именно stdcall

__>Нужно, чтобы при определении и при использовании сигнатуры совпадали.


__>
__>// В Dll
__>extern "C" __declspec(dllexport) void __stdcall Func()
__>{
__>}

__>// В Exe
__>extern "C" __declspec(dllimport) void __stdcall Func();
__>


Невозможно. К тому же когда так определяешь, всё равно получается что-то типа ?Func@XA. А в dll (не моей) функция определена именно как sdtcall с экспортным именем Func
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re[3]: Как импортировать функцию stdcall
От: _nn_  
Дата: 08.07.06 11:06
Оценка:
Здравствуйте, Ракопаукодав, Вы писали:

Р>Здравствуйте, _nn_, Вы писали:


__>>Здравствуйте, Ракопаукодав, Вы писали:


Р>>>Простите за глупый вопрос, ситуация такая:


Р>>>нужно в VS2005 импортировать из dll функцию stdcall, однако при запуске программы он вместо функции Func ищет функцию, типа ?Func@XXZZYYA.

Р>>>Использование директивы extern "C" не проходит, так как вызвать нужно именно stdcall

__>>Нужно, чтобы при определении и при использовании сигнатуры совпадали.


__>>
__>>// В Dll
__>>extern "C" __declspec(dllexport) void __stdcall Func()
__>>{
__>>}

__>>// В Exe
__>>extern "C" __declspec(dllimport) void __stdcall Func();
__>>


Р>Невозможно. К тому же когда так определяешь, всё равно получается что-то типа ?Func@XA. А в dll (не моей) функция определена именно как sdtcall с экспортным именем Func


Можно и так:
typedef void (__stdcall * func_type)();
func_type Func = reinterpret_cast<func_type>(GetProcAddress(dll, "Func"));

Func();
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 08.07.06 11:11
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Можно и так:

__>
__>typedef void (__stdcall * func_type)();
__>func_type Func = reinterpret_cast<func_type>(GetProcAddress(dll, "Func"));

__>Func();
__>


Это уже динамический импорт, так я и сам могу. А как статически? Неужели в Delphi можно, а в C++ нельзя?
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re[3]: Как импортировать функцию stdcall
От: gear nuke  
Дата: 08.07.06 11:35
Оценка:
Здравствуйте, Ракопаукодав, Вы писали:

Р>Невозможно. К тому же когда так определяешь, всё равно получается что-то типа ?Func@XA. А в dll (не моей) функция определена именно как sdtcall с экспортным именем Func


Дополнительно используйте def файл:
EXPORTS
Func=?Func@XA
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[5]: Как импортировать функцию stdcall
От: _nn_  
Дата: 08.07.06 11:44
Оценка: 1 (1) -1
Здравствуйте, Ракопаукодав, Вы писали:

Р>Здравствуйте, _nn_, Вы писали:


__>>Можно и так:

__>>
__>>typedef void (__stdcall * func_type)();
__>>func_type Func = reinterpret_cast<func_type>(GetProcAddress(dll, "Func"));

__>>Func();
__>>


Р>Это уже динамический импорт, так я и сам могу. А как статически? Неужели в Delphi можно, а в C++ нельзя?


Можно, через GetProcAddress.
Дело в том, что __declspec(dllimport) предназначен для совместного использования с __declspec(dllexport).

Можете воспользоваться Реализация отложенной загрузки библиотек на С++
Автор(ы): Андрей Солодовников
Дата: 20.03.2005
В данной статье описывается способ реализации отложенной загрузки динамических библиотек на С++ без использования механизма delayload, приведена реализация библиотеки отложенной загрузки и пример ее использования.

.

DL_USE_MODULE_BEGIN(some_dll, "some_dll.dll")
    DL_DECLARE_FUN(Func, void, (void))
DL_USE_MODULE_END()

using some_dll::Func;

Func();
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 08.07.06 12:10
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Ракопаукодав, Вы писали:


Р>>Невозможно. К тому же когда так определяешь, всё равно получается что-то типа ?Func@XA. А в dll (не моей) функция определена именно как sdtcall с экспортным именем Func


GN>Дополнительно используйте def файл:

GN>
GN>EXPORTS
GN>Func=?Func@XA
GN>


def-файл нужно использовать при компиляции dll, которую я не компилирую. а если бы и компилировал, то всё равно функция должна экспортироваться с именем Func

Или можно использовать такой def-файл и при импорте? Тогда что должно стоять в заголовке и куда его подключать?
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re[6]: Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 08.07.06 12:34
Оценка:
Здравствуйте, _nn_, Вы писали:

__>
__>DL_USE_MODULE_BEGIN(some_dll, "some_dll.dll")
__>    DL_DECLARE_FUN(Func, void, (void))
__>DL_USE_MODULE_END()

__>using some_dll::Func;

__>Func();
__>


Спасибо, это полезно, хотя моё любопытство по поводу принципиальной возможности именно статического импорта так и неудовлетворено
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re: Как импортировать функцию stdcall
От: alexeiz  
Дата: 09.07.06 02:03
Оценка:
Здравствуйте, Ракопаукодав, Вы писали:

Р>Простите за глупый вопрос, ситуация такая:


Р>нужно в VS2005 импортировать из dll функцию stdcall, однако при запуске программы он вместо функции Func ищет функцию, типа ?Func@XXZZYYA.

Р>Использование директивы extern "C" не проходит, так как вызвать нужно именно stdcall

У тебя скорее всего неправельный .lib файл, с которым ты линкуешь свой код. Посмотри, как там обзывается твоя функция с помощью dumpbin /exports yourlib.lib. Линкер, освовываясь на информации, которую он находит в lib файле, связывает твой код с динамически экспортируемыми функциями из dll. Поэтому если exe ищет ?Func@XXZZYYA, то это линкер связал его с ?Func@XXZZYYA.
Re[2]: Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 09.07.06 07:00
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Здравствуйте, Ракопаукодав, Вы писали:


Р>>Простите за глупый вопрос, ситуация такая:


Р>>нужно в VS2005 импортировать из dll функцию stdcall, однако при запуске программы он вместо функции Func ищет функцию, типа ?Func@XXZZYYA.

Р>>Использование директивы extern "C" не проходит, так как вызвать нужно именно stdcall

A>У тебя скорее всего неправельный .lib файл, с которым ты линкуешь свой код. Посмотри, как там обзывается твоя функция с помощью dumpbin /exports yourlib.lib. Линкер, освовываясь на информации, которую он находит в lib файле, связывает твой код с динамически экспортируемыми функциями из dll. Поэтому если exe ищет ?Func@XXZZYYA, то это линкер связал его с ?Func@XXZZYYA.


Я ошибся: это линковщик ищет ?Func@XXZZYYA. Lib-файл правильный
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re[3]: Как импортировать функцию stdcall
От: alexeiz  
Дата: 09.07.06 09:07
Оценка:
Здравствуйте, Ракопаукодав, Вы писали:

Р>Здравствуйте, _nn_, Вы писали:


__>>
__>>// В Dll
__>>extern "C" __declspec(dllexport) void __stdcall Func()
__>>{
__>>}

__>>// В Exe
__>>extern "C" __declspec(dllimport) void __stdcall Func();
__>>


Р>Невозможно. К тому же когда так определяешь, всё равно получается что-то типа ?Func@XA. А в dll (не моей) функция определена именно как sdtcall с экспортным именем Func


Ты что-то напутал. extern "C" __declspec(dllimport) void __stdcall Func(); приводит к импорту функции с недекорированным именем. Все Win32 функции так импортируются.
Re[4]: Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 09.07.06 10:18
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Здравствуйте, Ракопаукодав, Вы писали:


Р>>Здравствуйте, _nn_, Вы писали:


__>>>
__>>>// В Dll
__>>>extern "C" __declspec(dllexport) void __stdcall Func()
__>>>{
__>>>}

__>>>// В Exe
__>>>extern "C" __declspec(dllimport) void __stdcall Func();
__>>>


Р>>Невозможно. К тому же когда так определяешь, всё равно получается что-то типа ?Func@XA. А в dll (не моей) функция определена именно как sdtcall с экспортным именем Func


A>Ты что-то напутал. extern "C" __declspec(dllimport) void __stdcall Func(); приводит к импорту функции с недекорированным именем. Все Win32 функции так импортируются.


Нет, он импортирует функцию с декорированным именем: см. ошибку линковки
Error 1 error LNK2019: unresolved external symbol __imp__RunCalc@16 referenced in function _wmain ExportDll.obj

А вот если extern "C" __declspec(dllimport) void Func(); — тогда другое дело
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re[5]: Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 09.07.06 10:48
Оценка:
Здравствуйте, Ракопаукодав, Вы писали:


A>>Ты что-то напутал.

extern "C" __declspec(dllimport) void __stdcall Func();

приводит к импорту функции с недекорированным именем. Все Win32 функции так импортируются.

Р>Нет, он импортирует функцию с декорированным именем: см. ошибку линковки

Р>Error 1 error LNK2019: unresolved external symbol __imp__RunCalc@16 referenced in function _wmain ExportDll.obj

Р>А вот если

extern "C" __declspec(dllimport) void Func();

— тогда другое дело

_fnDllProject@0 — внешнее имя функции при
extern "C" __declspec(dllimport) void __stdcall Func();


?fnDllProject@@YGHXZ — экспортное имя функции при
__declspec(dllimport) void __stdcall Func();


fnDllProject
extern "C" __declspec(dllimport) void Func();


Но нужно stdcall, а extern "C" — cdecl
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re[5]: Как импортировать функцию stdcall
От: alexeiz  
Дата: 10.07.06 06:32
Оценка:
Здравствуйте, Ракопаукодав, Вы писали:

Р>Нет, он импортирует функцию с декорированным именем: см. ошибку линковки

Р>Error 1 error LNK2019: unresolved external symbol __imp__RunCalc@16 referenced in function _wmain ExportDll.obj

Значит у тебя количество параметров неправильное. @16 — это сколько байт на стеке являются параметрами к функции в __stdcall. В конвенции __stdcall функция сама очищает стек (ret 16 предполагается в твоём случае). Поэтому тот, кто её вызывает, должен заполнить стек правильным количеством параметров.
Re[6]: Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 10.07.06 08:28
Оценка: -2
Здравствуйте, alexeiz, Вы писали:

A>Здравствуйте, Ракопаукодав, Вы писали:


Р>>Нет, он импортирует функцию с декорированным именем: см. ошибку линковки

Р>>Error 1 error LNK2019: unresolved external symbol __imp__RunCalc@16 referenced in function _wmain ExportDll.obj

A>Значит у тебя количество параметров неправильное. @16 — это сколько байт на стеке являются параметрами к функции в __stdcall. В конвенции __stdcall функция сама очищает стек (ret 16 предполагается в твоём случае). Поэтому тот, кто её вызывает, должен заполнить стек правильным количеством параметров.


Это не у меня неправильно, а у тебя: модификатор
extern "C"

декларирует процедуру с соглашением о вызовах cdecl, а
__stdcall
— с соглашением stdcall, их просто нельзя вместе использовать
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re[7]: Что у меня неправильно сказано, ekamaloff?
От: Ракопаукодав  
Дата: 10.07.06 10:48
Оценка:
Здравствуйте, ekamaloff, Вы поставили мне минус, дак объясните.

Р>>>Нет, он импортирует функцию с декорированным именем: см. ошибку линковки

Р>>>Error 1 error LNK2019: unresolved external symbol __imp__RunCalc@16 referenced in function _wmain ExportDll.obj

A>>Значит у тебя количество параметров неправильное. @16 — это сколько байт на стеке являются параметрами к функции в __stdcall. В конвенции __stdcall функция сама очищает стек (ret 16 предполагается в твоём случае). Поэтому тот, кто её вызывает, должен заполнить стек правильным количеством параметров.


Р>Это не у меня неправильно, а у тебя: модификатор
extern "C"

Р> декларирует процедуру с соглашением о вызовах cdecl, а
__stdcall
— с соглашением stdcall, их просто нельзя вместе использовать
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Re[8]: Что у меня неправильно сказано, ekamaloff?
От: ekamaloff Великобритания  
Дата: 10.07.06 11:06
Оценка:
Здравствуйте, Ракопаукодав, Вы писали:

Р>Здравствуйте, ekamaloff, Вы поставили мне минус, дак объясните.


Да пожалуйста: extern "C" не имеет отношения к конвенции вызова.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[7]: Как импортировать функцию stdcall
От: MShura  
Дата: 10.07.06 11:11
Оценка: 1 (1)
Р>Это не у меня неправильно, а у тебя: модификатор
extern "C"

Р> декларирует процедуру с соглашением о вызовах cdecl, а
__stdcall
— с соглашением stdcall, их просто нельзя вместе использовать


extern "C" запрещает mangle имен

Я так думаю, что минус вам поставлен за то, что поленились почитать документацию, прежде чем утверждать неверные вещи.
Re[8]: Как импортировать функцию stdcall
От: Ракопаукодав  
Дата: 10.07.06 14:52
Оценка:
Здравствуйте, MShura, Вы писали:

Р>>Это не у меня неправильно, а у тебя: модификатор
extern "C"

Р>> декларирует процедуру с соглашением о вызовах cdecl, а
__stdcall
— с соглашением stdcall, их просто нельзя вместе использовать


MS>extern "C" запрещает mangle имен


MS>Я так думаю, что минус вам поставлен за то, что поленились почитать документацию, прежде чем утверждать неверные вещи.


1. Во первых, я не поленился. Я ведь не говорю что я гуру, могу и неправильно что-нибдуь понять
2. Если вы такой умный, скажите, почему в dll при extern "C" и __stdcall имена функций становятся типа Func@16 и как этого избежать. Минусы все ставить могут, а вот помочь советом почему-то за 2 дня ещё никто не смог
Поль вдруг вскочил и с необыкновенной живостью изобразил ракопаука. Отвратительный скрежещущий вой многоногого чудовища, пробирающегося через джунгли страшной Пандоры, огласил окрестности. И, словно в ответ, издалека донёсся глубокий ревущий вздох.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.