Не получается подключить dll
От: Аноним  
Дата: 29.11.10 09:14
Оценка:
Здравствуйте, уважаемые господа. На днях столкнулся с проблемой, суть следующая:

Имеется dll и заголовочный файл к ней. В заголовочном файле все функции объявлены так:
#define CALLCONV __stdcall
….
extern “C” RETURN_TYPE CALLCONV Fnc_Name(Parameters);

Подключая библиотеку статически, я менял CALLCONV на __declspec(dllimport) и на этапе выполнения проги в момент обращения к функциям получал ошибку:
Run-Time Check Failure #0 — The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

Подключая динамически, делал так (меняя CALLCONV обратно на __stdcall):

#typedef void (__stdcall PFN_FncName*)(parameters)

HINSTANCE handle = ::LoadLibrary((LPCSTR)("mydll.dll"));
PFN_FncName pfn_FncName = (PFN_FncName) ::GetProcAddress(handle, "FncName");

pfn_FncName(Parameters);

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


02.12.10 18:27: Перенесено модератором из 'C/C++' — Odi$$ey
Re: Не получается подключить dll
От: Сергей Мухин Россия  
Дата: 29.11.10 09:16
Оценка:
Здравствуйте, Аноним, Вы писали:

__stdcall должен быть и там и там (или не быть вообще)
---
С уважением,
Сергей Мухин
Re: Не получается подключить dll
От: uzhas Ниоткуда  
Дата: 29.11.10 09:20
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Подключая библиотеку статически, я менял CALLCONV на __declspec(dllimport)

надо не менять, а дополнять. конвенция вызовов ортогональна импорту\экспорту
http://www.experts-exchange.com/Programming/Languages/CPP/Q_10118794.html
Re[2]: Не получается подключить dll
От: achtung  
Дата: 29.11.10 10:05
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, Аноним, Вы писали:


А>>Подключая библиотеку статически, я менял CALLCONV на __declspec(dllimport)

U>надо не менять, а дополнять. конвенция вызовов ортогональна импорту\экспорту
U>http://www.experts-exchange.com/Programming/Languages/CPP/Q_10118794.html
Re: Не получается подключить dll
От: MasterZiv СССР  
Дата: 29.11.10 10:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, уважаемые господа. На днях столкнулся с проблемой, суть следующая:


А>Имеется dll и заголовочный файл к ней. В заголовочном файле все функции объявлены так:

А>#define CALLCONV __stdcall
А>….
А>extern “C” RETURN_TYPE CALLCONV Fnc_Name(Parameters);

А>Подключая библиотеку статически, я менял CALLCONV на __declspec(dllimport)


Ты делал это неправильно.

А>Подключая динамически, делал так (меняя CALLCONV обратно на __stdcall):


Ты делал это тоже неправильно.

А>В результате получал ту же самую ошибку. Как при статическом, так и при динамическом подключении вылетали не все функции. Некоторые выполнялись успешно.



Просто повезло.

А не так вот что: сначала нужно знать, что делаешь, потом делать.
Всю теорию сборки в С тебе тут излагать нет смысла -- её можно найти в книгах или инете.
Re[2]: Не получается подключить dll
От: alexander51  
Дата: 01.12.10 11:12
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, уважаемые господа. На днях столкнулся с проблемой, суть следующая:


А>>Имеется dll и заголовочный файл к ней. В заголовочном файле все функции объявлены так:

А>>#define CALLCONV __stdcall
А>>….
А>>extern “C” RETURN_TYPE CALLCONV Fnc_Name(Parameters);

А>>Подключая библиотеку статически, я менял CALLCONV на __declspec(dllimport)


MZ>Ты делал это неправильно.


А>>Подключая динамически, делал так (меняя CALLCONV обратно на __stdcall):


MZ>Ты делал это тоже неправильно.


А>>В результате получал ту же самую ошибку. Как при статическом, так и при динамическом подключении вылетали не все функции. Некоторые выполнялись успешно.



MZ>Просто повезло.


MZ>А не так вот что: сначала нужно знать, что делаешь, потом делать.

MZ>Всю теорию сборки в С тебе тут излагать нет смысла -- её можно найти в книгах или инете.

Я понимаю, что без книжек далеко не уедешь. Прошу прощения за то, что не упомянул в первом посте про то, что я имею очень скудные познания в C, а теперь в этом нет смысла, т.к. это и так уже стало понятно. Но на чтение книжек уйдут месяцы, а эта библиотека нужна мне в рабочем состоянии чем быстрее, тем лучше. Поэтому я и не прошу Вас излагать тут всю теорию сборки C, а лишь «слегка», в двух словах, как это сделали первые ответившие, подсказать, что не так.

Также прошу прощения за синтаксические ошибки в своем первом посте, т.к. я писал его по памяти, не имея под рукой кода.
Сергей, uhaz, сбасибо большое, я понял ошибку — __stdcall в хэдере должен быть. Но непонятно, почему не работает случай динамического подключения. Ведь там хэдер от библиотеки вообще не используется, а __stdcall стоит в объявлении типа указателя на функцию. Подскажите пожалуйста… Провел довольно много времени за соответствующими статьями в инете, не нашел причину…
Код во вложении.
http://files.rsdn.ru/94922/DynamicCNC.cpp
Re[3]: Не получается подключить dll
От: Сергей Мухин Россия  
Дата: 01.12.10 11:51
Оценка:
Здравствуйте, alexander51, Вы писали:

A> __stdcall в хэдере должен быть. Но непонятно, почему не работает случай динамического подключения. Ведь там хэдер от библиотеки вообще не используется, а __stdcall стоит в объявлении типа указателя на функцию. Подскажите пожалуйста… Провел довольно много времени за соответствующими статьями в инете, не нашел причину…

A>Код во вложении.
A>http://files.rsdn.ru/94922/DynamicCNC.cpp

ошибка про несответсвия ESP возникает (при включённой опции компилятора) в след случаях:
1. различная callingconversion (в MSWin32 основные: thiscall, ccall, stdcall, fastcall)
2. несовпадение числа и/или типов параметров

при этом типы должны быть разными по размеру в стеке. например double против int будет ошибка, а int против char нет.

ps
1. код безполезен, т.к. нет объявлений
2. не адо так много цитировать
3. надо форматировать текст использую кнопочки
---
С уважением,
Сергей Мухин
Re[3]: Не получается подключить dll
От: MasterZiv СССР  
Дата: 01.12.10 13:40
Оценка: -1
On 01.12.2010 14:12, alexander51 wrote:

> в этом нет смысла, т.к. это и так уже стало понятно. Но на чтение книжек уйдут

> месяцы, а эта библиотека нужна мне в рабочем состоянии чем быстрее, тем лучше.
> Поэтому я и не прошу Вас излагать тут всю теорию сборки C, а лишь «слегка», в
> двух словах, как это сделали первые ответившие, подсказать, что не так.

Лучший совет: обратитесь к профессионалам, раз так надо, но не умеете.
Так просто это за 5 мин. не объясниш.

---
Имеется dll и заголовочный файл к ней.
---

Этого для подключения библиотеки МАЛО. нужно иметь библиотеку ипморта ещё.
Posted via RSDN NNTP Server 2.1 beta
Re: Не получается подключить dll
От: MasterZiv СССР  
Дата: 01.12.10 13:41
Оценка: -1
On 29.11.2010 12:14, Аноним 38 wrote:
> Подключая динамически, делал так (меняя CALLCONV обратно на __stdcall):
>
> #typedef void (__stdcall PFN_FncName*)(parameters)
> …
> HINSTANCE handle = ::LoadLibrary((LPCSTR)("mydll.dll"));
> PFN_FncName pfn_FncName = (PFN_FncName) ::GetProcAddress(handle, "FncName");
> …
> pfn_FncName(Parameters);


Это -- неверный способ вызова функции из .DLL. Он может работать, а может
и НЕ работать.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Не получается подключить dll
От: uzhas Ниоткуда  
Дата: 01.12.10 15:49
Оценка:
Здравствуйте, alexander51, Вы писали:

A>Ведь там хэдер от библиотеки вообще не используется, а __stdcall стоит в объявлении типа указателя на функцию. Подскажите пожалуйста…


хедер как раз желательно использовать, ибо там правильное объявление экспортируемой функции
к сожалению, вы выложили мало кода (при длл и ее интерфейс забыли)
могу дать советы только в режиме телепатии:
1) используйте extern "C" когда объявляете функцию из чужой длл, скорей всего она имеет С-стайл декорирование
2) всегда проверяйте, что вернула GetProcAddress на ноль. сразу возвращайте ошибку, чтобы программа не падала
то же самое относится к LoadLibrary
3) возможно, в длл функция имеет другую сигнатуру и вы передаете неправильное число\тип аргументов
Re[4]: Не получается подключить dll
От: Сергей Мухин Россия  
Дата: 01.12.10 16:31
Оценка:
Здравствуйте, uzhas, Вы писали:

U>хедер как раз желательно использовать, ибо там правильное объявление экспортируемой функции


Желательно, но для динамического может и не помочь.
И в добавок, тут может быть одна тонкость. Если в хедере нет явного объявления calling convencion, то это может быть перекрыто опциями компилятора (проекта). Поэтому рекомедоуванно всегда ставить явно для библиотек (в т.ч. и импортных)

U>1) используйте extern "C" когда объявляете функцию из чужой длл, скорей всего она имеет С-стайл декорирование

необязательно

U>2) всегда проверяйте, что вернула GetProcAddress на ноль. сразу возвращайте ошибку, чтобы программа не падала

обязательно!
но вроде заявленная ошибка другая.

U>3) возможно, в длл функция имеет другую сигнатуру и вы передаете неправильное число\тип аргументов

ага
---
С уважением,
Сергей Мухин
Re[4]: Не получается подключить dll
От: MasterZiv СССР  
Дата: 02.12.10 09:05
Оценка:
On 01.12.2010 18:49, uzhas wrote:

> 1) используйте extern "C" когда объявляете функцию из чужой длл, скорей всего

> она имеет С-стайл декорирование

Неверно. Стайл может быть любой.

> 2) всегда проверяйте, что вернула GetProcAddress на ноль. сразу возвращайте

> ошибку, чтобы программа не падала
> то же самое относится к LoadLibrary
+1

А ещё -- не применяйте вообще динамическую загрузку DLL. Через линкер только.

> 3) возможно, в длл функция имеет другую сигнатуру и вы передаете неправильное

> число\тип аргументов

+1
Posted via RSDN NNTP Server 2.1 beta
Re[5]: Не получается подключить dll
От: uzhas Ниоткуда  
Дата: 02.12.10 15:45
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>On 01.12.2010 18:49, uzhas wrote:


>> 1) используйте extern "C" когда объявляете функцию из чужой длл, скорей всего

>> она имеет С-стайл декорирование

MZ>Неверно. Стайл может быть любой.

я не утверждаю, что должен быть только Си-стайл при работе с длл
я посоветовал ТС его сменить, ибо

Имеется dll и заголовочный файл к ней. В заголовочном файле все функции объявлены так:
#define CALLCONV __stdcall
….
extern “C” RETURN_TYPE CALLCONV Fnc_Name(Parameters);

Подключая динамически, делал так (меняя CALLCONV обратно на __stdcall):

#typedef void (__stdcall PFN_FncName*)(parameters)

Re[6]: Не получается подключить dll
От: alexander51  
Дата: 02.12.10 20:12
Оценка:
Нашел, из-за чего — дурацкая ошибка из-за невнимательности
PFN_HidInitialize pfn_HidInitialize =(PFN_HidInitialize)GetProcAddress(hMyDll,"CmdMoveAxesDelta")

Не CmdMoveAxesDelta, а HidInitialize называется эта функция в библиотеке. Понятно — CmdMoveAxesDelta принимает аргументы, а HidInitialize — нет, поэтому похоже и все рушилось. Теперь от Run-Time Check Failure #0, кажется, избавился. Это при динамическом подключении. Хэдер я не подключал, взял оттуда только enum CNC_ERROR.
Что касается связывания через линкер.

Этого для подключения библиотеки МАЛО. нужно иметь библиотеку ипморта ещё.

Библиотека импорта — это lib? Я сделал файл def, используя dumpbin, из него — lib с помощью lib.exe. Подключил хэдер. Подключил lib при помощи #pragma comment (вместо прагмы ставил и в свойствах проекта). Ошибка unresolved external.
Спасибо большое Вам за советы, я посмотрю всё внимательно и, думаю, уже справлюсь Хэдер тут: http://files.rsdn.ru/94922/CNCUSBControllerAPI.h
Re[7]: Не получается подключить dll
От: MasterZiv СССР  
Дата: 03.12.10 07:10
Оценка:
On 02.12.2010 23:12, alexander51 wrote:

> Не CmdMoveAxesDelta, а HidInitialize называется эта функция в библиотеке.

> Понятно — CmdMoveAxesDelta принимает аргументы, а HidInitialize — нет, поэтому
> похоже и все рушилось. Теперь от Run-Time Check Failure #0, кажется, избавился.
> Это при динамическом подключении. Хэдер я не подключал, взял оттуда только enum
> CNC_ERROR.

Думаю, это только кажется.


> Библиотека импорта — это lib?


Да.

Я сделал файл def, используя dumpbin, из него —
> lib с помощью lib.exe. Подключил хэдер. Подключил lib при помощи #pragma comment
> (вместо прагмы ставил и в свойствах проекта). Ошибка unresolved external.

0) процесс .exe -> dumpbin -> .def -> .lib не всегда однозначно восстанавливает
всю информацию.

1) Пожет таки где-то ошибся.

Почему бы просто не взять из дистрибутива .lib и с ним собрать ?
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.