Форум программистов, компьютерный форум CyberForum.ru

Динамическое подключение DLL - C++

Восстановить пароль Регистрация
 
Goido Kodaka
0 / 0 / 0
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 20:42     Динамическое подключение DLL #1
Здравствуйте! Скорее всего, мой вопрос покажется вам глупым, но всё же... Я не могу динамически подключить библиотеку. Когда подключаю статически, всё работает, функция выдает ответ и все счастливы. Но когда начинаю подключать статически, в момент вызова функции программа ломается, выдавая: Необработанное исключение по адресу 0x776B1A91 в DetCalcDynamic.exe: 0xC0000005: нарушение прав доступа при исполнении по адресу 0x00000000.
C++
1
2
3
4
HINSTANCE hLib = LoadLibrary(L"DetFunctions.dll");
int(*detFunc)(int[20][20], int) = (int(*) (int[20][20],int))GetProcAddress(hLib, "Calculate");
int result = detFunc(k, n);
FreeLibrary(hLib);
Вот по сути весь фрагмент кода, в котором я работаю с библиотекой. Сама библиотека находится нужном месте(hLib прошел проверку !=NULL, когда пытался отлаживать). Функция в библиотеке точно называется Calculate. И типы параметров совпадают... В чем проблема - ума не приложу, волосы на голове уже рву Может, у кого-нибудь есть мысли на этот счет? Заранее спасибо.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.05.2014, 20:42     Динамическое подключение DLL
Посмотрите здесь:

C++ подключение dll
подключение dll C++
Подключение dll библиотеки C++
Подключение dll - ошибка C++
C++ Подключение dll (C++) к проекту VB 6.0
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,297
Завершенные тесты: 1
03.05.2014, 21:10     Динамическое подключение DLL #2
Вариант 1.

Функция в dll использует одно соглашение о вызовах (например, _stdcall), а в
клиентском коде подразумевается другое (например, _cdecl).

Вариант 2.

GetProcAddress завершается с ошибкой, потому что такой функции в
dll все-таки нету. Но Вы это не проверяете (кстати, почему ?), поэтому
ошибка пробрасывается дальше, в строку 3 (кстати, не проверять
ошибки - опасная практика).

Судя по тексту сообщения (нарушение прав доступа при исполнении по
адресу 0x00000000), склоняюсь в сторону варианта 2.
Goido Kodaka
0 / 0 / 0
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 21:13  [ТС]     Динамическое подключение DLL #3
Цитата Сообщение от Убежденный Посмотреть сообщение
GetProcAddress завершается с ошибкой, потому что такой функции в
dll все-таки нету. Но Вы это не проверяете (кстати, почему ?), поэтому
ошибка пробрасывается дальше, в строку 3 (кстати, не проверять
ошибки - опасная практика).
Хм... чтобы проверить нашла ли программа dll достаточно проверить дескриптор на не NULL, а как можно проверить найдена ли сама функция? Не могли бы вы, пожалуйста, подсказать И насчет первого варианта, как его можно проверить?
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,297
Завершенные тесты: 1
03.05.2014, 21:19     Динамическое подключение DLL #4
Проверьте, что возвращает GetProcAddress. В случае ошибки будет NULL.
Подробная информация тогда ищется в GetLastError.

Вы уверены, что функция точно называется Calculate, а не, к примеру,
_Calculate@8 или как-нибудь еще ? Компиляторы любят искажать имена
при экспорте из dll, и не все вьюеры правильно их показывают.
Подсказка: используйте dumpbin (есть в Windows SDK / Visual Studio),
он-то уж точно покажет экспортируемые из dll имена, точь в точь.
Goido Kodaka
0 / 0 / 0
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 21:23  [ТС]     Динамическое подключение DLL #5
Цитата Сообщение от Убежденный Посмотреть сообщение
Вы уверены, что функция точно называется Calculate, а не, к примеру,
_Calculate@8 или как-нибудь еще ? Компиляторы любят искажать имена
при экспорте из dll, и не все вьюеры правильно их показывают.
Не думаю, что она как-то еще называется. Просто если я подключаю в этом же проекте dll статически, то есть заголовочный файл подключаю, включаю в проект lib-файл и вызываю функцию Calculate, то всё прекрасно отрабатывает

Цитата Сообщение от Убежденный Посмотреть сообщение
Проверьте, что возвращает GetProcAddress. В случае ошибки будет NULL.
Подробная информация тогда ищется в GetLastError.
Спасибо, посмотрю
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,297
Завершенные тесты: 1
03.05.2014, 21:33     Динамическое подключение DLL #6
Цитата Сообщение от Goido Kodaka Посмотреть сообщение
Не думаю, что она как-то еще называется. Просто если я подключаю в этом же проекте dll статически, то есть заголовочный файл подключаю, включаю в проект lib-файл и вызываю функцию Calculate, то всё прекрасно отрабатывает
Когда функция экспортируется из dll, компоновщик может присвоить
ей какое-то особое имя. Например, добавить ведущее подчеркивание,
различные символы по краям и т.п. При статической компоновке и для
библиотеки, и для клиентского кода, который ее использует, все это
прозрачно. А вот при динамической загрузке, когда вы сами зовете
LoadLibrary и GetProcAddress, становится важным указывать точное
имя экспорта. В общем, если загрузите сюда вашу dll-ку, я покажу
все, что написал выше, на практике.
Goido Kodaka
0 / 0 / 0
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 21:42  [ТС]     Динамическое подключение DLL #7
О, спасибо большое, буду очень благодарен
Вложения
Тип файла: rar DetFunctions.rar (8.1 Кб, 5 просмотров)
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,297
Завершенные тесты: 1
03.05.2014, 21:46     Динамическое подключение DLL #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Препарируем "пациента":

dumpbin.exe /EXPORTS /RAWDATA:NONE DetFunctions.dll
Код
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file D:\System\SharedFolder\DetFunctions.dll

File Type: DLL

  Section contains the following exports for DetFunctions.dll

    00000000 characteristics
    536507B2 time date stamp Sat May 03 18:13:54 2014
        0.00 version
           1 ordinal base
           3 number of functions
           3 number of names

    ordinal hint RVA      name

          1    0 00011087 ?Calculate@@YAHQAY0BE@HH@Z
          2    1 00011186 ?CalculateDeterminator@@YAHQAY0BE@HHHH@Z
          3    2 00011096 ?Odd@@YA_NH@Z

  Summary

        1000 .data
        1000 .idata
        2000 .rdata
        1000 .reloc
        1000 .rsrc
        4000 .text
       10000 .textbss
Обратите внимание, как на самом деле называется функция Calculate -
?Calculate@@YAHQAY0BE@HH@Z
Goido Kodaka
0 / 0 / 0
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 21:51  [ТС]     Динамическое подключение DLL #9
Цитата Сообщение от Убежденный Посмотреть сообщение
Обратите внимание, как на самом деле называется функция Calculate -
?Calculate@@YAHQAY0BE@HH@Z
Сам бы я никогда не догадался до такого... Да и гугл молчит... Теперь всё заработало Спасибо вам большое!
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,297
Завершенные тесты: 1
03.05.2014, 21:56     Динамическое подключение DLL #10
Цитата Сообщение от Goido Kodaka Посмотреть сообщение
Теперь всё заработало
Только не говорите, что написали это имя (?Calculate@@YAHQAY0BE@HH@Z) в
GetProcAddress. Правильный способ решения таких проблем - делать экспорт
так, чтобы имена не искажались. Это достигается с помощью DEF-файла.
Правда, в этом случае с экспортом C++-классов возникнут затруднения,
но тут уж приходится выбирать: или "странное" и непереносимое имя с
потенциальными проблемами в будущем, или "чистый" экспорт, но с ограниченными
возможностями.
Goido Kodaka
0 / 0 / 0
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 22:00  [ТС]     Динамическое подключение DLL #11
Цитата Сообщение от Убежденный Посмотреть сообщение
Только не говорите, что написали это имя (?Calculate@@YAHQAY0BE@HH@Z) в
GetProcAddress.
Пойман с поличным
Цитата Сообщение от Убежденный Посмотреть сообщение
Это достигается с помощью DEF-файла.
Можно поподробнее насчет этого? Не отказался бы от новых знаний
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,297
Завершенные тесты: 1
03.05.2014, 22:09     Динамическое подключение DLL #12
Ищите по форуму. Например: Как верно экспортить функцию?

И еще:

Name Decoration
http://msdn.microsoft.com/en-us/library/deaxefa7.aspx

Calling Conventions
http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx

Exporting from a DLL
http://msdn.microsoft.com/en-us/library/z4zxe9k8.aspx
Goido Kodaka
0 / 0 / 0
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 22:10  [ТС]     Динамическое подключение DLL #13
Спасибо еще раз, вы очень мне помогли
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11810 / 6789 / 767
Регистрация: 27.09.2012
Сообщений: 16,840
Записей в блоге: 2
Завершенные тесты: 1
03.05.2014, 22:23     Динамическое подключение DLL #14
Ну и что касается экпорта классов:
Дональд Бокс: Сущность технологии COM
описываются способы экспорта с минимальной зависимостью от транслятора
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.08.2014, 23:16     Динамическое подключение DLL
Еще ссылки по теме:

Подключение Dll на С++ к Java и С# C++
C++ Динамическое подключение VC++ (2012) DLL в приложении C++Builder (RAD XE5)
C++ Динамическое связывание DLL

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

Или воспользуйтесь поиском по форуму:
koraven
0 / 0 / 1
Регистрация: 11.08.2014
Сообщений: 4
11.08.2014, 23:16     Динамическое подключение DLL #15
Делаю похожую задачу. Однако проблема другая. Функция из dll вызывается правильная. Можно даже зайти в нее через F11, но при попытке открытия COM порта с помощью CreateFile выпадает
Первый этап обработки исключения по адресу 0x00021478 в dll_check.exe: 0xC0000005: нарушение прав доступа при исполнении по адресу 0x00021478.
Необработанное исключение по адресу 0x00021478 в dll_check.exe: 0xC0000005: нарушение прав доступа при исполнении по адресу 0x00021478.
C++
1
2
3
4
extern "C" _declspec(dllexport) int connectAr(){
HANDLE hSerial;
    LPCTSTR sPortName = L"COM3";
    hSerial = ::CreateFile(sPortName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Если сделать экзешник с этим же кодом, то порт открывается и обмен данными идет. Не могу найти информацию, какие длл должны быть зарегистрированы regsvr'ом. Может из-за этого. Еще думаю на второй ноль в параметрах функции. Этим параметром вроде задается SECURITY_DESCRIPTOR, но не могу понять за что он конкретно отвечает.
Yandex
Объявления
11.08.2014, 23:16     Динамическое подключение DLL
Ответ Создать тему
Опции темы

Текущее время: 21:04. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru