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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 5.00
NativeLand
0 / 0 / 0
Регистрация: 27.12.2010
Сообщений: 46
#1

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

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

Добрый день ... Полазил по форумам и гайдам ....
Пишу такой вот 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.07.2013, 00:33
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Не могу вызвать функцию из .dll (C++):

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

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

Не могу вызвать функцию - C++
код функцииtemplate &lt;class T&gt;//Прямой void Tree&lt;T&gt;::streight(Node *root) { if(!root) return; // printf(&quot;%d. \&quot;%s\&quot;\n&quot;, ++cnt,...

Как вызвать функцию, описанную в DLL через Custom Action в wix? - C++
Не нашел подходящего раздела для вопроса, поэтому решил сделать здесь, тк DLL написана на c++! Вот сама DLL:#include &lt;stdio.h&gt; ...

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

Вызвать функцию из dll с неопределённым числом параметров - C++
Нужно вызвать из dll функцию с неопределённым числом параметров. пока что работаю с таким вызовом char res; char (*dll) (char* ...);...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Praktolock
65 / 65 / 1
Регистрация: 29.11.2011
Сообщений: 300
22.07.2013, 05:27 #2
а ты dumpbin запусти и посмотри таблицу экспорта у твоей dll
0
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
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
NativeLand
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
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
22.07.2013, 18:10 #5
NativeLand, в .cpp файле функции тоже оберни в extern "C" {}
0
NativeLand
0 / 0 / 0
Регистрация: 27.12.2010
Сообщений: 46
22.07.2013, 20:31  [ТС] #6
Обернул .срр в extern "C" .. ничего не поменялось... Есть еще идеи?..

Добавлено через 4 минуты
Обернул .срр в extern "C" ... Не помогло есть еще идеи?
0
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
22.07.2013, 21:32 #7
Кинь исходники архивом.
0
Praktolock
65 / 65 / 1
Регистрация: 29.11.2011
Сообщений: 300
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
NativeLand
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", что не могу собрать библиотеку?...
0
Вложения
Тип файла: rar dll.rar (475 байт, 7 просмотров)
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
23.07.2013, 12:35 #10
Проблема в .def-файле, там имена функций другие. Я, честно говоря, вообще не знаю зачем он нужен, я при компиляции .dll никогда его не использовал. Попробуй его вообще убрать.
0
Praktolock
65 / 65 / 1
Регистрация: 29.11.2011
Сообщений: 300
23.07.2013, 12:50 #11
Цитата Сообщение от lazybiz Посмотреть сообщение
Я, честно говоря, вообще не знаю зачем он нужен
Студия, например, когда скомпилирует длл, в таблицу экспорта поместит только декорированные имена вида
Цитата Сообщение от NativeLand Посмотреть сообщение
?function@@YAHHH@Z
?function2@@YANNN@Z
Соответственно, их будет неудобно юзать линкуя динамически, так как GetProcAdress не найдёт функции function и function1. Для этого и нужен раздел EXPORTS .def файла, чтобы дать экспортируемым функциям (и не только) альтернативные недекорированные имена.
0
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
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
Praktolock
65 / 65 / 1
Регистрация: 29.11.2011
Сообщений: 300
23.07.2013, 12:55 #13
Цитата Сообщение от NativeLand Посмотреть сообщение
где туплю в кодах при extern "C", что не могу собрать библиотеку?
Убери вообще extern "c", зачем тебе оно, если ты не знаешь что это(ну если конечно и длл и экзешник ты в одном и том же компиляторе делаешь). Главное чтобы у тебя экпортируемые и импортируемые функции были одинаково обьявлены.
0
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
23.07.2013, 12:58 #14
NativeLand, где ты взял эти имена:
?function@@YAHHH@Z
?function2@@YANNN@Z
?
0
Praktolock
65 / 65 / 1
Регистрация: 29.11.2011
Сообщений: 300
23.07.2013, 12:58 #15
Цитата Сообщение от lazybiz Посмотреть сообщение
Разве MSVS не создает .lib для подключения либы
Для статической линковки - да. Но, как мы видим в коде ТС'а, он пытается линковать динамически, с помощью GetProcAddress, которая ни о lib файле, ни упаси бог, о декорировании ничего не знает
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.07.2013, 12:58
Привет! Вот еще темы с ответами:

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

Как правильно вызвать функцию с указателем на другую функцию как параметр - C++
Вот вариант: double f(double x) { ... } double k(double (*f)(double), double y) { ...

Не получается вызвать функцию - C++
Есть функция &quot;void __fastcall TForm1::Image2MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)&quot; ...

Вызвать функцию заново - C++
Вот мой код, в котором двучлен раскладывается на квадратное уравнение. int Function(int x1, int x2){ if (x1&lt;0 &amp;&amp; x2&lt;0){ ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
23.07.2013, 12:58
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru