|  | 
 
 | 
| 
 | |||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
|  | 
|  | Опции темы | Поиск в этой теме | Опции просмотра | 
|  | 
| 
			 
			#1  
			
			
			
			
		 | ||||
| 
 | ||||
|  Делфийская 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  
			
			
			
			
		 | ||||
| 
 | ||||
|   Цитата: 
 Во-вторых, 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); |