0 / 0 / 1
Регистрация: 08.04.2014
Сообщений: 16
1

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

03.05.2014, 20:42. Показов 6950. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! Скорее всего, мой вопрос покажется вам глупым, но всё же... Я не могу динамически подключить библиотеку. Когда подключаю статически, всё работает, функция выдает ответ и все счастливы. Но когда начинаю подключать статически, в момент вызова функции программа ломается, выдавая: Необработанное исключение по адресу 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. И типы параметров совпадают... В чем проблема - ума не приложу, волосы на голове уже рву Может, у кого-нибудь есть мысли на этот счет? Заранее спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.05.2014, 20:42
Ответы с готовыми решениями:

Динамическое подключение VC++ (2012) DLL в приложении C++Builder (RAD XE5)
Здравствуйте! Вроде бы подобные темы бывали, но я так и не смог понять, что не так, т.к. редко пишу...

Динамическое связывание DLL
Как создавать библиотеку dll и чтобы работала программа, которую я напишу? Как осуществить...

Динамическое подключение библиотек C++ MinGW
Импользую VS Code и MinGW. Нужно динамически подключить несколько библиотек. Но при вызове...

Динамическое подключение DLL, которая в свою очередь использует другие DLL
Здравствуйте! Направьте на путь истинный, как поступить след. образом: Пишу небольшое...

14
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
03.05.2014, 21:10 2
Вариант 1.

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

Вариант 2.

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

Судя по тексту сообщения (нарушение прав доступа при исполнении по
адресу 0x00000000), склоняюсь в сторону варианта 2.
1
0 / 0 / 1
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 21:13  [ТС] 3
Цитата Сообщение от Убежденный Посмотреть сообщение
GetProcAddress завершается с ошибкой, потому что такой функции в
dll все-таки нету. Но Вы это не проверяете (кстати, почему ?), поэтому
ошибка пробрасывается дальше, в строку 3 (кстати, не проверять
ошибки - опасная практика).
Хм... чтобы проверить нашла ли программа dll достаточно проверить дескриптор на не NULL, а как можно проверить найдена ли сама функция? Не могли бы вы, пожалуйста, подсказать И насчет первого варианта, как его можно проверить?
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
03.05.2014, 21:19 4
Проверьте, что возвращает GetProcAddress. В случае ошибки будет NULL.
Подробная информация тогда ищется в GetLastError.

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

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

Решение

Препарируем "пациента":

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
1
0 / 0 / 1
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 21:51  [ТС] 9
Цитата Сообщение от Убежденный Посмотреть сообщение
Обратите внимание, как на самом деле называется функция Calculate -
?Calculate@@YAHQAY0BE@HH@Z
Сам бы я никогда не догадался до такого... Да и гугл молчит... Теперь всё заработало Спасибо вам большое!
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
03.05.2014, 21:56 10
Цитата Сообщение от Goido Kodaka Посмотреть сообщение
Теперь всё заработало
Только не говорите, что написали это имя (?Calculate@@YAHQAY0BE@HH@Z) в
GetProcAddress. Правильный способ решения таких проблем - делать экспорт
так, чтобы имена не искажались. Это достигается с помощью DEF-файла.
Правда, в этом случае с экспортом C++-классов возникнут затруднения,
но тут уж приходится выбирать: или "странное" и непереносимое имя с
потенциальными проблемами в будущем, или "чистый" экспорт, но с ограниченными
возможностями.
0
0 / 0 / 1
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 22:00  [ТС] 11
Цитата Сообщение от Убежденный Посмотреть сообщение
Только не говорите, что написали это имя (?Calculate@@YAHQAY0BE@HH@Z) в
GetProcAddress.
Пойман с поличным
Цитата Сообщение от Убежденный Посмотреть сообщение
Это достигается с помощью DEF-файла.
Можно поподробнее насчет этого? Не отказался бы от новых знаний
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
03.05.2014, 22:09 12
Ищите по форуму. Например: Как верно экспортить функцию?

И еще:

Name Decoration
http://msdn.microsoft.com/en-u... xefa7.aspx

Calling Conventions
http://msdn.microsoft.com/en-u... 2ssfy.aspx

Exporting from a DLL
http://msdn.microsoft.com/en-u... xe9k8.aspx
1
0 / 0 / 1
Регистрация: 08.04.2014
Сообщений: 16
03.05.2014, 22:10  [ТС] 13
Спасибо еще раз, вы очень мне помогли
0
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.05.2014, 22:23 14
Ну и что касается экпорта классов:
Дональд Бокс: Сущность технологии COM
описываются способы экспорта с минимальной зависимостью от транслятора
1
0 / 0 / 0
Регистрация: 11.08.2014
Сообщений: 4
11.08.2014, 23:16 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, но не могу понять за что он конкретно отвечает.
0
11.08.2014, 23:16
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.08.2014, 23:16
Помогаю со студенческими работами здесь

Динамическое подключение dll
существует dll с классами ну например Namespace MyDll Public Class MyFunc Public...

dll динамическое подключение
что не правильно? #include<iostream> #include<Windows.h> #include<conio.h> typedef...

dll динамическое подключение
Задача вот какая, нужно подключить длл но динамически if fileexist('mydll') then connect else ...

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


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

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

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