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

Не работает функция DLL с параметрами

06.08.2009, 09:11. Показов 2750. Ответов 15
Метки нет (Все метки)

Доброго всем времени суток. Без параметров функция работает. Как только начинаю передавать параметры
Не работает функция DLL с параметрами

На рисунке видно, что это не DLL, а EXE файл. Но в принципе разницы нет, в DLL происходит тоже самое.
Функцию для экспорта объявляю как и положено
extern "C" __declspec (dllexport)
С прежних моих ассемблерных экспериментов, помню что возвращаемое значение функции храниться в регистре аккумуляторе, а передаваемые значения передаются через стек. В общем то у каждого процесса свое адресное пространство и свой стек. И когда я хачу чужую программу то запрашиваю в его адресном пространстве область памяти для себя и потом специальными API функциями перегоняю данные туда обратно.
Но в случае DLL ведь должно быть по другому. Ведь когда я подключаю чужую DLL и вызываю оттуда функции с параметрами, у меня все нормально происходит. Тогда почему сам не могу написать DLL с функциями которым передаются параметры?
При гуглении нахожу в инете только классические примеры с функциями без параметров. Кроме конечно DllMain.
Где я ошибаюсь, подскажите пожалуйста....
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.08.2009, 09:11
Ответы с готовыми решениями:

Dll: функция с входными параметрами
Простейший пример: Dll library TestDll; uses SysUtils, Classes; procedure...

C# dll функция с output параметрами в Delphi
Здравствуйте, есть следующая функция написана на шарпе и помещена в dll библиотеку: namespace...

Функция CopyFile работает не со всеми параметрами
Подскажите, пожалуйста. Почему так работает: if...

Не работает функция dll
Подключил библиотеку dll к проекту через "linker",подключил заголовочный файл библиотеки dll,...

15
1664 / 1133 / 80
Регистрация: 21.08.2008
Сообщений: 4,725
Записей в блоге: 1
06.08.2009, 09:22 2
код то дай...
0
0 / 0 / 0
Регистрация: 28.07.2009
Сообщений: 17
06.08.2009, 14:41  [ТС] 3
mdll.zip
В Debug, программа grebdll.exe загружает DLL. При правом клике мыши вызывается функция из DLL без передаваемых параметров, при левом с параметрами.
0
Эксперт С++
3064 / 1404 / 423
Регистрация: 19.01.2009
Сообщений: 3,808
06.08.2009, 16:16 4
ну тут все просто:

В файле GREBDLL.CPP, функции объявлены вот так
C++
1
2
BOOL (WINAPI *PFN_GetNum) (int);
BOOL (WINAPI *PFN_GetVoid)(void);
А в keymouse.cpp вот так
C++
1
2
3
4
5
6
7
8
9
10
11
extern "C" __declspec(dllexport) 
int GetNum(int a)
{
 return a;
}
 
extern "C" __declspec(dllexport) 
int GetVoid(void)
{
 return 5;
}
А в grebdll.cpp прототипы функции должны быть объявлены вот так:
C++
1
2
int (*PFN_GetNum) (int);
void (*PFN_GetVoid)(void);
1
1664 / 1133 / 80
Регистрация: 21.08.2008
Сообщений: 4,725
Записей в блоге: 1
06.08.2009, 16:58 5
как сказали выше - тип ф-ции в длл и прототип указателя на ф-ю должны совпадать...
а для чего надо указатель на ф-ю копировать?
C++
1
memcpy(&PFN_GetNum,&R,sizeof(PFN_GetNum));
не легче сразу было написать:
C++
1
2
3
4
5
6
7
8
9
// это в определениях
typedef int (* PFN_GetNum)( int );
PFN_GetNum myfunc;
 
// это в исполняемой части:
 
myfunc = GetProcAddress(hMyDll,"GetNum");
if (myfunc)
   myfunc(5);
0
0 / 0 / 0
Регистрация: 28.07.2009
Сообщений: 17
06.08.2009, 18:03  [ТС] 6
Цитата Сообщение от polivets Посмотреть сообщение
А в grebdll.cpp прототипы функции должны быть объявлены вот так:
C++
1
2
int (*PFN_GetNum) (int);
void (*PFN_GetVoid)(void);
Большое спасибо! Сработало. На автомате перенес установки с чужого проекта, а вдуматься не хватило ума. Кстати, а какую установку несёт WINAPI? Какая схема работы с вызовами?
0
1664 / 1133 / 80
Регистрация: 21.08.2008
Сообщений: 4,725
Записей в блоге: 1
06.08.2009, 18:04 7
#define WINAPI __stdcall
1
0 / 0 / 0
Регистрация: 28.07.2009
Сообщений: 17
06.08.2009, 18:31  [ТС] 8
Цитата Сообщение от oxotnik Посмотреть сообщение
как сказали выше - тип ф-ции в длл и прототип указателя на ф-ю должны совпадать...
а для чего надо указатель на ф-ю копировать?
C++
1
memcpy(&PFN_GetNum,&R,sizeof(PFN_GetNum));
не легче сразу было написать:
C++
1
2
3
4
5
6
7
8
9
// это в определениях
typedef int (* PFN_GetNum)( int );
PFN_GetNum myfunc;
 
// это в исполняемой части:
 
myfunc = GetProcAddress(hMyDll,"GetNum");
if (myfunc)
   myfunc(5);
Я попытался присвоить сразу, но у меня компилятор ругается на несовпадение типа. Попытался привести к типу, но не получилось. Что бы долго не мучиться, просто скопировал один указатель в другой. Когда компилил на Borland 5.0, приводилось к типу нормально, без проблем. На Visual C вот такая ошибка получается

Добавлено через 4 минуты 42 секунды
Цитата Сообщение от oxotnik Посмотреть сообщение
#define WINAPI __stdcall
Понятно. Тогда лучше в DLL, так и объявлять, потому что в конечном счете ее вызывать будут из Дельфей, а не из Си. Еще раз спасибо!

Добавлено через 15 минут 24 секунды
Что то не получается в DLL подставить WINAPI. Получается какой то конфликт с именем функции. Её вид в DLL выглядит как _GetNum@4
Объявлял
extern "C" __declspec(dllexport)
int WINAPI GetNum(int a)
{
return a;
}

Че опять не так?
0
Эксперт С++
3064 / 1404 / 423
Регистрация: 19.01.2009
Сообщений: 3,808
06.08.2009, 20:13 9
Тогда лучше в DLL, так и объявлять, потому что в конечном счете ее вызывать будут из Дельфей
Дельфи поддерживает такие сalling conventions : register, pascal, cdecl, stdcall и safecall. Так что выбирайте, что душе угодно, с поддерживает 2-4 типы (на счет остальных точно не помню). Я бы остоновился на cdecl

grabdll.cpp
C++
1
2
int (* __cdecl PFN_GetNum) (int);
int (* __cdecl PFN_GetVoid)(void);
keymouse.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
extern "C" __declspec(dllexport) 
int __cdecl GetNum(int a)
{
 return a;
}
 
extern "C" __declspec(dllexport) 
int __cdecl GetVoid(void)
{
 return 5;
}
0
0 / 0 / 0
Регистрация: 28.07.2009
Сообщений: 17
06.08.2009, 20:30  [ТС] 10
Мне конечно нравиться чисто сишный вариант, который Вы и предлагаете. То есть я должен написать, как выше и сказать Дельфистам применить вызов cdecl. Правильно?
И они меня поймут?
0
Эксперт С++
3064 / 1404 / 423
Регистрация: 19.01.2009
Сообщений: 3,808
06.08.2009, 20:42 11
Смотря какие программисты... а то и понять не смогут... вот пример, как вызывать из дельфи:
Delphi
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
26
27
28
29
30
31
32
33
34
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;
 
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
function GetNum(a : integer) : integer; cdecl; external 'keymouse' name 'GetNum';
function GetVoid : integer; cdecl; external 'keymouse' name 'GetVoid';
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  ShowMessage(IntToStr(GetNum(1)));
  ShowMessage(IntToStr(GetVoid));
end;
 
end.
0
0 / 0 / 0
Регистрация: 28.07.2009
Сообщений: 17
06.08.2009, 20:42  [ТС] 12
Цитата Сообщение от polivets Посмотреть сообщение
Дельфи поддерживает такие сalling conventions : register, pascal, cdecl, stdcall и safecall. Так что выбирайте, что душе угодно, с поддерживает 2-4 типы (на счет остальных точно не помню). Я бы остоновился на cdecl

grabdll.cpp
C++
1
2
int (* __cdecl PFN_GetNum) (int);
int (* __cdecl PFN_GetVoid)(void);
А если не для CPP, а для ДЕЛЬФИ, как должна выглядеть запись выше?


Пока сформулировал вопрос, Вы уже отвечаете. Большое спасибо за пример. Мне он очень пригодиться для общения с Дельфистами. А то мы не всегда друг, друга понимаем
0
schdub
06.08.2009, 20:43
  #13

Не по теме:

400 сообщение - поздравьте меня :)

1
0 / 0 / 0
Регистрация: 28.07.2009
Сообщений: 17
06.08.2009, 20:51  [ТС] 14
В Сочи по ходу много умных ребят. Вы не первый с этого города мне помогаете. Поздравляю с 400 постом. Всех благ Вам и удачи!

Ведь не только в море можете плескаться
0
schdub
06.08.2009, 21:14
  #15

Не по теме:

Цитата Сообщение от was Посмотреть сообщение
В Сочи по ходу много умных ребят. Вы не первый с этого города мне помогаете.
Как не странно, но это я и есть :)

0
0 / 0 / 0
Регистрация: 28.07.2009
Сообщений: 17
06.08.2009, 21:21  [ТС] 16
Будете богатым Олег, я Вас не узнал Как там с поездкой в Ростов?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.08.2009, 21:21
Помогаю со студенческими работами здесь

Не работает функция из dll библиотеки
Здравствуйте. Помогите, пожалуйста, найти неполадки. В приложении нужно ввести в один Edit число, а...

Не работает простая функция из DLL библиотеки
Создал DLL-ку по примеру. Добавил в нее свою функцию "Plus". Когда вызываю ее, она ничего не делает...

Функция MapAndLoad() работает с dll-файлом, не работает с exe-файлом
Доброго времени суток. Объясните, почему программа #include <windows.h> #include <imagehlp.h>...

Функция в dll не работает, если в ней объявляется массив double 10.000 x 100
Недавно работаю в Visual C++ expreess и стрлкнулся с аспектом, описанным ниже. Может быть кто-то...


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

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

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