не экпортируется с-интерфейс ?
Видимо из-за этого?
#define MT4_EXPFUNC extern __declspec(dllexport)
Видимо из-за этого?
Вот функция экспортируется:
__declspec(dllexport) int __stdcall GetIntValue(const int ipar);
Попробуйте вызвать эту функцию в режиме run-time linking из с++ программы, не получится,
GetProcAddress(hinstLib, "GetIntValue") не найдет это имя.
Но если экпортировать эту функцию вот так:
extern "C" __declspec(dllexport) int __stdcall GetIntValue(const int ipar),
то GetProcAddress(hinstLib, "GetIntValue") нормально находит эту функцию.
Разобрался, может кому пригодиться, да и сам могу забыть.
Методы экспорта и вызова DLL функций методом run-time linking /load-time linking:
1. Экспорт __declspec(dllexport) int __stdcall GetIntValue(const int ipar) {...}
или так extern "C" __declspec(dllexport) int __stdcall GetIntValue(const int ipar) {...}
Вызов, таким образом экспортированных функций возможен только механизмом load-time linking
2. Если поменять работу со стеком при вызове с __stdcall на __cdecl, т.е. экспортировать вот так:
Экспорт __declspec(dllexport) int __cdecl GetIntValue(const int ipar) {...}
или так extern "C" __declspec(dllexport) int __cdecl GetIntValue(const int ipar) {...},
то вызов, таким образом экспортированных функций возможен как механизмом load-time linking,
так и механизмом run-time linking.
3. Экспортируемые функции идут без всякой "оранжировки":
так - int __stdcall GetIntValue(const int ipar) {...} или
так - int __cdecl GetIntValue(const int ipar) {...}
В этом случае применение .def файла при сборке обеспечит оба механизма вызова - load-time linking и run-time linking
4. Самое хорошее - применение .def файла при сборке обеспечит оба механизма вызова - load-time linking и run-time linking также для случаев 1. и 2. Т.е. .def файл имеет приоритет над другими способами экспорта, если они присутствуют !
Я тоже озадачивался данными вопросами и пришёл к выводу, что имеется проблема в компиляторе Майкрософта. У меня стоит Студия 2010, не знаю как на других версиях. В общем, если мы указываем
extern "C" __declspec(dllexport) int __stdcall Func(....)
то по какой-то причине компилятор изменяет (коверкает) конечное имя функции в DLL, несмотря на параметр extern "C", запрещающий это делать. Т.е. на выходе мы получаем что-то вроде _Func@4. Уж не знаю, баг это или фича такая... Ведь extern "C" специально предназначен для сохранения оригинального имени. А тут такое...
Если же указана директива __cdecl (либо ничего не указано), то имя функции компилируется без искажений, как и положено. Поэтому и получается, что нормально экспортируется только этот вариант. Но для МТ4 он не подходит.
А вот в С++ Билдере всё экспортируется без проблем в обоих случаях, имя функции не меняется. Поэтому и МТ4 её нормально видит. И кстати в Билдере можно ещё использовать __export вместо __declspec(dllexport), тоже нормально работает.
Я думал может в настройках Студии надо что-то изменить (или в настройках проекта), но покопавшись так ничего и не нашёл такого. Может кто знает?
Рантайм возможно неправильно задан.
С/C++ -- Code Generation -- Runtime Library. Надо MultiThreaded или MultiThreaded Debug (в завиимости от конфигурации), ЕМНИП. Вобщем пощелкайте это свойство.
А вообще имена функций задаются в def файле. Неважно какой вид они имеют. Опять же ЕМНИП.
Рантайм возможно неправильно задан.
С/C++ -- Code Generation -- Runtime Library. Надо MultiThreaded или MultiThreaded Debug (в завиимости от конфигурации), ЕМНИП. Вобщем пощелкайте это свойство.
А вообще имена функций задаются в def файле. Неважно какой вид они имеют. Опять же ЕМНИП.
Может всё-же MultiThreadedDll/MultiThreadedDebugDll ? Речь ведь о Dll как-никак. Впрочем я попробовал все варианты, не помогает.
Что касается использования def-файла - это всё конечно понятно. Но речь о том, что всё должно работать и без этого файла. В MSDN ведь так и сказано, что __declspec(dllexport) позволяет обойтись без def файла. А в итоге выходит, что обойтись то конечно можно, но с искажёнными именами.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Смотрю внимательно пример DLL из дистрибутива.
Для быстрой справки приведу его здесь:
Вроде как нормальный экспорт всех функций.
Для вызова этих функций МТ4 очевидно использует run-time linking, т.е.,
выдает сначала
HINSTANCE hinstLib = LoadLibrary(TEXT("ExpertSample.dll"));
а затем, к примеру, для GetIntValue :
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "GetIntValue");
и т.д....
В МТ4 все это работает.
Вопрос такой - каким образом МТ4 удается выполнить GetProcAddress(...), если при экпорте
не экпортируется с-интерфейс ? Ведь МТ4 написан, вроде как, на с++.
Я пробовал из с++ программы вызвать ExpertSample.dll - функции, однако GetProcAddress(...)
выдает ошибку 127 - не удается найти указанную dll-функцию.
Если же при экспорте, функции экспортировать вместе с-интерфейсом, т.е. делать так:
extern "C" __declspec(dllexport) int __stdcall GetIntValue(const int ipar)
{
printf("GetIntValue takes %d\n",ipar);
return(ipar);
}
то вызов из с++ программы проходит нормально.