Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/29: Рейтинг темы: голосов - 29, средняя оценка - 4.62
0 / 0 / 0
Регистрация: 27.12.2010
Сообщений: 46
1

Не могу вызвать функцию из .dll

22.07.2013, 00:33. Показов 5607. Ответов 36
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день ... Полазил по форумам и гайдам ....
Пишу такой вот header:
C++
1
2
extern "C++" __declspec(dllexport) int function (int,int);
extern "C++" __declspec(dllexport) double function2(double,double);
Далее непосредственно сам .cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
#include "mbdll.h"
 
int function(int a, int b)
{
    return a*b;
}
 
double function2(double a,double b)
{
    return a/b;
}
И потом .def файлик:
C++
1
2
3
4
LIBRARY
EXPORTS
function = ?function@@YAHHH@Z PRIVATE
function2 = ?function2@@YANNN@Z PRIVATE

Теперь сам проект из которого явным способом пытаюсь вызвать функции (.dll добавил в проект через Shift+Alt+A):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "stdafx.h"
#include "windows.h"
#include <iostream>
 
int _tmain(int argc, _TCHAR* argv[])
{
    typedef int (*Add1)(int a, int b);
    typedef double (*Add2)(double a, double b);
 
    HMODULE hmod = LoadLibrary((LPCWSTR)"mbdll.dll");
    
    Add1 fun1= (Add1) GetProcAddress(hmod, "function");
    Add2 fun2= (Add2) GetProcAddress(hmod, "function2");
    if (fun1 || fun2)
    {
        std::cout<<fun1(3,3)<<std::endl;
        std::cout<<fun2(3,3)<<std::endl;
    }
    else
        std::cout<<"Cannot get function address\n";
 
    FreeLibrary( hmod );
    system("PAUSE");
    return 0;
}
И мне выдает "Cannot get function address" ... Если просто вызываю без if функции .. компилит но вылетает ошибка при выполнении исходника ...
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.07.2013, 00:33
Ответы с готовыми решениями:

Не могу вызвать функцию из dll С++ в С# в системе Win 7 64bit, MSVS 2008
Здравствуйте! Уже два дня не могу вызвать функцию из dll C++ в программе, написанная в C#....

Вызвать функцию из dll с неопределённым числом параметров
Нужно вызвать из dll функцию с неопределённым числом параметров. пока что работаю с таким вызовом ...

Как из DLL вызвать функцию, находящуюся в exe?
Плз. скажите, как из DLL вызвать функцию, находящуюся в exe'шнике. Плз.! Плз.! Плз.!

Не могу вызвать функцию
код функцииtemplate &lt;class T&gt;//Прямой void Tree&lt;T&gt;::streight(Node *root) { if(!root) return;...

36
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
22.07.2013, 05:27 2
а ты dumpbin запусти и посмотри таблицу экспорта у твоей dll
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
22.07.2013, 06:47 3
Цитата Сообщение от NativeLand Посмотреть сообщение
extern "C++"
Надо писать extern "C"

Добавлено через 4 минуты
Еще необходимо указать calling convention: __stdcall

Добавлено через 25 минут
Пример для MinGW:
Кликните здесь для просмотра всего текста
test.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
#ifdef __cplusplus
extern "C" {
#endif
 
void __stdcall test() {
    std::cout << "hello from dll\n";
}
 
#ifdef __cplusplus
}
#endif

Кликните здесь для просмотра всего текста
main.cpp
C++
1
2
3
4
5
6
7
extern "C" void __stdcall test();
 
int main()
{
    test();
    return 0;
}

Кликните здесь для просмотра всего текста
Makefile
Bash
1
2
3
4
5
6
7
8
9
10
11
SRC = test.cpp main.cpp
OBJ = $(SRC:.cpp=.o)
 
all: dll main.o
    g++ -s -L. -o main.exe main.o -ltest.dll
 
dll: test.o
    g++ -s -shared -o test.dll test.o -Wl,--out-implib,libtest.dll.a
 
%.o: %.cpp
    g++ -c -Wall -O2 $*.cpp -o $@
0
0 / 0 / 0
Регистрация: 27.12.2010
Сообщений: 46
22.07.2013, 17:03  [ТС] 4
Цитата Сообщение от lazybiz Посмотреть сообщение
Надо писать extern "C"

Добавлено через 4 минуты
Еще необходимо указать calling convention: __stdcall

Добавлено через 25 минут
Подправил но теперь не могу собрать библиотеку...:
вот header:
C++
1
2
3
4
5
6
7
8
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) int __stdcall function (int,int);
__declspec(dllexport) double __stdcall function2(double,double);
#ifdef __cplusplus
}
#endif
вот сам .cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
#include "mbdll.h"
 
int __stdcall function(int a, int b)
{
    return a*b;
}
 
double __stdcall function2(double a,double b)
{
    return a/b;
}
Ошибки:
1>mbdll.exp : error LNK2001: unresolved external symbol "int __cdecl function(int,int)" (?function@@YAHHH@Z)
1>mbdll.exp : error LNK2001: unresolved external symbol "double __cdecl function2(double,double)" (?function2@@YANNN@Z)
1>C:\Users\emm\Desktop\mbdll\Debug\mbdll.dll : fatal error LNK1120: 2 unresolved externals

В def файле ничего не менял.... В чем трабл теперь?...

П.С.: таблица экспорта:
?function@@YAHHH@Z
?function2@@YANNN@Z
function
function2
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
22.07.2013, 18:10 5
NativeLand, в .cpp файле функции тоже оберни в extern "C" {}
0
0 / 0 / 0
Регистрация: 27.12.2010
Сообщений: 46
22.07.2013, 20:31  [ТС] 6
Обернул .срр в extern "C" .. ничего не поменялось... Есть еще идеи?..

Добавлено через 4 минуты
Обернул .срр в extern "C" ... Не помогло есть еще идеи?
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
22.07.2013, 21:32 7
Кинь исходники архивом.
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
23.07.2013, 05:08 8
C++
1
HMODULE hmod = LoadLibrary((LPCWSTR)L"mbdll.dll");
Добавлено через 3 минуты
Такое чуство, что у тебя просто библиотека не загружается, так как включен юникод и ты пытаешься юникод-версии LoadLibrary (то есть LoadLibraryW) передать указатель на анси строку "mbdll.dll". Попробуй всё таки передать ей юникод строку.

Добавлено через 1 минуту
или лучше используй макрос:
C++
1
HMODULE hmod = LoadLibrary((LPCWSTR)_T("mbdll.dll"));
1
0 / 0 / 0
Регистрация: 27.12.2010
Сообщений: 46
23.07.2013, 12:26  [ТС] 9
Цитата Сообщение от lazybiz Посмотреть сообщение
Кинь исходники архивом.
Прикрепил...
Цитата Сообщение от Praktolock Посмотреть сообщение
C++
1
HMODULE hmod = LoadLibrary((LPCWSTR)L"mbdll.dll");
Добавлено через 3 минуты
Такое чуство, что у тебя просто библиотека не загружается, так как включен юникод и ты пытаешься юникод-версии LoadLibrary (то есть LoadLibraryW) передать указатель на анси строку "mbdll.dll". Попробуй всё таки передать ей юникод строку.

Добавлено через 1 минуту
или лучше используй макрос:
C++
1
HMODULE hmod = LoadLibrary((LPCWSTR)_T("mbdll.dll"));
Да, действительно .. заминка была именно в этом. Спасибо!!
Но теперь другой все ж таки вопрос .. где туплю в кодах при extern "C", что не могу собрать библиотеку?...
Вложения
Тип файла: rar dll.rar (475 байт, 8 просмотров)
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
23.07.2013, 12:35 10
Проблема в .def-файле, там имена функций другие. Я, честно говоря, вообще не знаю зачем он нужен, я при компиляции .dll никогда его не использовал. Попробуй его вообще убрать.
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
23.07.2013, 12:50 11
Цитата Сообщение от lazybiz Посмотреть сообщение
Я, честно говоря, вообще не знаю зачем он нужен
Студия, например, когда скомпилирует длл, в таблицу экспорта поместит только декорированные имена вида
Цитата Сообщение от NativeLand Посмотреть сообщение
?function@@YAHHH@Z
?function2@@YANNN@Z
Соответственно, их будет неудобно юзать линкуя динамически, так как GetProcAdress не найдёт функции function и function1. Для этого и нужен раздел EXPORTS .def файла, чтобы дать экспортируемым функциям (и не только) альтернативные недекорированные имена.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
23.07.2013, 12:55 12
A module-definition (.def) file is a text file containing one or more module statements that describe various attributes of a DLL. If you are not using the __declspec(dllexport) keyword to export the DLL's functions, the DLL requires a .def file.
.def-файл вовсе не обязателен. Модификаторы extern "C", __stdcall и __declspec(dllexport) сделают это за него.
Разве MSVS не создает .lib для подключения либы чтобы не юзать LoadLibrary и GetProcAddress ?
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
23.07.2013, 12:55 13
Цитата Сообщение от NativeLand Посмотреть сообщение
где туплю в кодах при extern "C", что не могу собрать библиотеку?
Убери вообще extern "c", зачем тебе оно, если ты не знаешь что это(ну если конечно и длл и экзешник ты в одном и том же компиляторе делаешь). Главное чтобы у тебя экпортируемые и импортируемые функции были одинаково обьявлены.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
23.07.2013, 12:58 14
NativeLand, где ты взял эти имена:
?function@@YAHHH@Z
?function2@@YANNN@Z
?
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
23.07.2013, 12:58 15
Цитата Сообщение от lazybiz Посмотреть сообщение
Разве MSVS не создает .lib для подключения либы
Для статической линковки - да. Но, как мы видим в коде ТС'а, он пытается линковать динамически, с помощью GetProcAddress, которая ни о lib файле, ни упаси бог, о декорировании ничего не знает
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
23.07.2013, 13:00 16
Зачем усложнять себе жизнь, если можно подключить import-library. Сомневаюсь что VS этого не умеет.
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
23.07.2013, 13:00 17
ТС, оставь в .def файле просто
LIBRARY
EXPORTS
function
function2
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
23.07.2013, 13:02 18
Если оставляешь .def-файл - тогда удаляй __declspec(dllexport) и наоборот.
http://msdn.microsoft.com/en-u... 80%29.aspx
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
23.07.2013, 13:02 19
Цитата Сообщение от lazybiz Посмотреть сообщение
Сомневаюсь что VS этого не умеет.
А другие компиляторы, с другими правилами декорирования, поймут эти имена?
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
23.07.2013, 13:06 20
Цитата Сообщение от Praktolock Посмотреть сообщение
А другие компиляторы, с другими правилами декорирования, поймут эти имена?
В самом начале статьи пример.
extern "C" совместно с __stdcall намного упрощают этот процесс.

Добавлено через 42 секунды
NativeLand, какая версия студии?
0
23.07.2013, 13:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.07.2013, 13:06
Помогаю со студенческими работами здесь

Как вызвать функцию, описанную в DLL через Custom Action в wix?
Не нашел подходящего раздела для вопроса, поэтому решил сделать здесь, тк DLL написана на c++! ...

Не могу вызвать функцию через указатель
Есть функция void matrixsqr(int **a, int N, int M) как ее вызвать через указатель на функцию ...

Могу ли я поменять какую-нибудь функцию в готовой dll-ке?
Прошу прощенья за тупой вопрос! Но! Могу ли я поменять какую-нибудь функцию в готовой dll-ке? Если...

Вызвать функцию из dll
V8.1 В справке по 1С есть инфа, как подключить dll-ку. Но вот только не написано как вызвать...


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

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