Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Делфийская DLL и основная программа C++

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки

Открыть новую тему     Написать ответ в эту тему

MrGalaxy



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Доброго времени!
 
DLL:

Код:
library M3_78M;
 
var N: integer;
 
{$R *.res}
 
function GetValue(PM:pointer; out PN:pointer): boolean; stdcall; Export;
 var M: integer;
     MM: ^integer;
Begin
 GetValue:=false;
 
 MM:=PM;
 M:=MM^;
 N:=M+1;
 PN:=@N;
 
 GetValue:=true;
end;
 
{----------------------------------------------------------------------}
 
Exports GetValue;
 
begin
end.

 
Осн. прога:

Код:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{
 hM3_dll = LoadLibrary("M3_78M.dll");
 GetValue =(TGetValue)GetProcAddress(hM3_dll,"GetValue");
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 int  Mumber,    // Входной параметр
  *AMumber,   // Указатель (адрес) входного параметра
   Number,    // Выходной параметр
  *ANumber,   // Указатель (адрес) выходного параметра
    **AANumber;  // Указатель (адрес) указателя (адреса) вых. параметра
 
// Присвоение значения входному параметру
 Mumber=StrToInt(Edit2->Text);
// В качестве входного параметра подпрограммы
//  используются указатель (адрес)
 AMumber=&Mumber;
 
// В качестве выходного параметра подпрограммы
//  используются указатель указателя
// (адрес адреса)
 AANumber=&ANumber;
 
 GetValue(AMumber, AANumber);    // Вызов подпрограммы
 
// Извлечение значения выходного параметра по указателю
 Number=*ANumber;
 Edit1->Text=IntToStr(Number);
 
 Application->ProcessMessages();
}
 
//---------------------------------------------------------------------------

Заголовок:

Код:
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TButton *Button1;
    TEdit *Edit1;
    TEdit *Edit2;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormActivate(TObject *Sender);
private:    // User declarations
public:  // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//====================================================================//
 typedef bool (WINAPI *TGetValue)(int*, int**);  // ** !
 TGetValue GetValue;
 HINSTANCE hM3_dll;
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

 
Проект простой. На форме одна кнопка и два поля TEdit. По нажатии на кнопку происходит увеличение содержимого Edit2 на единицу и результат заносится в Edit1.
 
Почему в C++ входной параметр воспринимается как ссылка, а выходной - как ссылка ссылки?
При этом, если основная прога написана на Делфи, то всё ожидаемо: и входной, и выходной параметры воспринимаются как ссылки на числа.
 
Извращался по всякому. И cdecl ставил, и var вместо out. Один фиг...
 
Это так задумано, или я где-то накосячил? Полдня лопатил всемирную помойку, ничего не нашёл.
Подскажите, плз., если кто сталкивался.

Всего записей: 1868 | Зарегистр. 11-01-2007 | Отправлено: 16:36 08-11-2013
Dmitry

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
MrGalaxy
 
Out (или var) параметр это в сущности указатель на место, куда нужно положить результат. Т.е. указатель на указатель на int это и есть ссылка ссылки. Так что все правильно.  
А что именно не работает?
Логика работы dll-ки мне совершенно не понятна Зачем результат вычислений класть в глобальную переменную dll-ки чтобы затем вернуть на нее указатель? Если речь идет об увеличении на 1 целого числа (понятно конечно что это просто пример, но тем не менее) то зачем там вообще указатели? Почему не написать просто:
 
function GetValue(var PM: integer): boolean; stdcall; export;
begin
  PM:=PM+1;
  Result:=true;
end;

Всего записей: 81 | Зарегистр. 24-09-2003 | Отправлено: 20:20 08-11-2013
MrGalaxy



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Out (или var) параметр это в сущности указатель на место, куда нужно положить результат. Т.е. указатель на указатель на int это и есть ссылка ссылки. Так что все правильно.  

Благодарю, уже разобрался.
 

Цитата:
А что именно не работает?
Это и не работает. Пытаюсь обратиться как к ссылке, а надо как к ссылке ссылки.
 

Цитата:
Логика работы dll-ки мне совершенно не понятна  
Это как пример, нарочито дубовый, не оптимизированный. Демонстрация передачи параметров. Увеличение на 1 для того, чтобы просто видеть, что в dll-ке что-то там происходит, что она не молчит.
Если давать указатель на локальную переменную, то вычисленное значение теряется, не передаётся.
 

Всего записей: 1868 | Зарегистр. 11-01-2007 | Отправлено: 15:37 09-11-2013
Dmitry

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
MrGalaxy

Цитата:
Это и не работает. Пытаюсь обратиться как к ссылке, а надо как к ссылке ссылки.

 
Я не очень хорошо разбираюсь в C++, но мне кажется:
 
вот здесь:
// В качестве выходного параметра подпрограммы
//  используются указатель указателя
// (адрес адреса)
 AANumber=&ANumber;  
не нужно присваивания, т.к. адрес переменной для указателя на int будет присвоен в dll-ке
 
вот здесь:
// Извлечение значения выходного параметра по указателю
 Number=*ANumber;  
вообще не понятно что хотелось, в dll-ке вроде в ANumber кладется указатель на int, но сишная прога, судя по хедеру, ждет в этом параметре указатель на указатель на int.  
 
Поэтому я и говорю, что логика dll-ки мне совершенно не понятна.
 
Указатель на локальную переменную давать естественно нельзя, т.к. она будет уничтожена после выхода из контекста процедуры в dll-ке.
 
Почему просто не передать в dll-ку указатель на переменную из основной проги, которую нужно в dll-ке изменить? Зачем возвращать указатель как var параметр?  

Всего записей: 81 | Зарегистр. 24-09-2003 | Отправлено: 22:18 09-11-2013 | Исправлено: Dmitry, 22:19 09-11-2013
MrGalaxy



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
 AANumber=&ANumber;   не нужно присваивания, т.к. адрес переменной для указателя на int будет присвоен в dll-ке   

Я пробовал, без этого не работает.
 

Цитата:
вот здесь:  // Извлечение значения выходного параметра по указателю   Number=*ANumber;   вообще не понятно что хотелось, в dll-ке вроде в ANumber кладется указатель на int, но сишная прога, судя по хедеру, ждет в этом параметре указатель на указатель на int.  

Здесь можно было обойтись без этой переменной и написать сразу

Код:
Edit1->Text=*ANumber;

Промежуточную переменную я ввёл для большей наглядности.
 

Цитата:
Почему просто не передать в dll-ку указатель на переменную из основной проги, которую нужно в dll-ке изменить? 
Я, когда писал программу, сразу попытался так сделать, почему-то не пошло у меня. Почитал книжки и Интернет, везде сказано, что выходной параметр может быть только out-var, вот и поверил. Теперь знаю, что можно. И Вы подсказали, и на Киберфоруме пообщался.

Всего записей: 1868 | Зарегистр. 11-01-2007 | Отправлено: 10:41 10-11-2013 | Исправлено: MrGalaxy, 10:43 10-11-2013
Открыть новую тему     Написать ответ в эту тему

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Делфийская DLL и основная программа C++


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru