Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Программа и интерфейс
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 08.11.2013, 20:18
Аватар для MrGalaxy
MrGalaxy MrGalaxy вне форума
Прохожий
 
Регистрация: 08.11.2013
Адрес: город самоваров и пряников
Сообщения: 1
Версия Delphi: RAD Studio 2007
Репутация: 10
По умолчанию Делфийская DLL и основная программа C++, передача агрументов туда-сюда

Здравствуйте!

Имеется
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. Один фиг...

Это так задумано, или я где-то накосячил? Полдня лопатил всемирную помойку, ничего не нашёл.
Подскажите, плз., если кто сталкивался.
Ответить с цитированием
  #2  
Старый 08.11.2013, 22:56
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
function GetValue(PMointer; out PNointer): boolean; stdcall; Export;
var M: integer;
MM: ^integer;
Begin
GetValue:=false;

MM:=PM;
M:=MM^;
N:=M+1;
PN:=@N;

GetValue:=true;
end;
Во-первых, не ссылка, а указатель. Надо различать.
Во-вторых, cdecl тут вообще ни при чем, т.к. соглашения вызовов регламентируют порядок параметров в стеке/регистрах и ответственность за стек.
В-третьих, все очевидно. PM - pointer, то есть void *. PN - тоже pointer, однако должен еще иметь возможность изменяться, следовательно в функцию надо передать указатель на указатель.
И получается, что вызывать надо
Код:
int MNumber;
int *ANumber;
...
GetValue(&MNumber, &ANumber); 
А конструкция
Код:
int *Mumber,
 Mumber=StrToInt(Edit2->Text);
 AMumber=&Mumber;
логически неверна, хотя работать будет. Указателю присваивается число.
Делфи же работает "ожидаемо" только потому, что он out/var параметры скрывает. Также можно и для плюсов:
Код:
bool (WINAPI *TGetValue)(int *, int *&); 
...
int MNumber;
int *ANumber;
...
GetValue(&MNumber, ANumber); 
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:23.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter