Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.11.2013, 20:06   #1
MrGalaxy
Новичок
Джуниор
 
Аватар для MrGalaxy
 
Регистрация: 08.11.2013
Сообщений: 4
По умолчанию Делфийская 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. Один фиг...

Это так задумано, или я где-то накосячил? Полдня лопатил всемирную помойку, ничего не нашёл.
Подскажите, плз., если кто сталкивался.

Последний раз редактировалось MrGalaxy; 09.11.2013 в 12:48. Причина: какие-то лишние звёздочки сами по себе были вставлены при копировании, убрал их
MrGalaxy вне форума Ответить с цитированием
Старый 08.11.2013, 22:37   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А ты не ставь Out вообще. Пусть туда просто указатель передается.
P.S. Если честно я не очень понял смысл функции в ДЛЛ...
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 08.11.2013, 22:42   #3
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

function GetValue(PM:Pinteger; var PN:Pinteger): BOOL; stdcall; Export;?
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 08.11.2013, 23:11   #4
MrGalaxy
Новичок
Джуниор
 
Аватар для MrGalaxy
 
Регистрация: 08.11.2013
Сообщений: 4
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
А ты не ставь Out вообще. Пусть туда просто указатель передается.
Без комментариев.

Цитата:
Сообщение от Slym Посмотреть сообщение
function GetValue(PM:Pinteger; var PN:Pinteger): BOOL; stdcall; Export;?
Я же писал, что и var пробовал, и разные типы указателей. Всё без толку. А от типа функции вообще ничего не зависит, хоть void (procedure) ставь.

Последний раз редактировалось Stilet; 08.11.2013 в 23:57.
MrGalaxy вне форума Ответить с цитированием
Старый 08.11.2013, 23:57   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Без комментариев.
Что ж. Не буду отвлекать. Удачи.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.11.2013, 00:17   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

А глюк вот где:
Код:
 typedef bool (WINAPI *TGetValue)(int*, int**); *// ** !
 TGetValue GetValue;
 HINSTANCE hM3_dll;
для C++ стандарт cldcl, а не stdcall. И где же объявление, что это функция?

Почему бы не динам. загрузка?
Код:
bool (__stdcall Func*)(int AM*,int AAN**);
HINSTANCE hDLL = LoadLibrary("LOL4TO.DLL");
Func = (bool (__stdcall *)(int*,int**))GetProcAddress(hDll,"GetValue");
На заметку:
В dll, доп. флаг eport не нужен, если вы сами закинули функцию в exports.
Человек_Борща вне форума Ответить с цитированием
Старый 09.11.2013, 11:08   #7
MrGalaxy
Новичок
Джуниор
 
Аватар для MrGalaxy
 
Регистрация: 08.11.2013
Сообщений: 4
По умолчанию

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
А глюк вот где:
Код:
 typedef bool (WINAPI *TGetValue)(int*, int**); *// ** !
 TGetValue GetValue;
 HINSTANCE hM3_dll;
для C++ стандарт cldcl, а не stdcall.
WINAPI - это и есть stdcall.

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
И где же объявление, что это функция?
bool после typedef. Процедура описывается войдом.

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
Почему бы не динам. загрузка?
А я по Вашему как загружаю? Код посмотрите.

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
На заметку:
В dll, доп. флаг eport не нужен, если вы сами закинули функцию в exports.
Действительно, работает. Спасибо.
MrGalaxy вне форума Ответить с цитированием
Старый 09.11.2013, 11:18   #8
MrGalaxy
Новичок
Джуниор
 
Аватар для MrGalaxy
 
Регистрация: 08.11.2013
Сообщений: 4
По умолчанию

В общем, накосячил не я. Это - особенность делфийских out и var, они добавляют лишнюю ссылку. Объяснили на Киберфоруме.
DLL переписал:

Код:
library M3_78M;

uses Windows;

{$R *.res}

function GetValue(PM:Pointer; out N:Integer): BOOL; stdcall;
 var M: Integer;
     MM: PInteger;
Begin
 GetValue:=false;

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

 GetValue:=true;
end;

{----------------------------------------------------------------------}

Exports GetValue;

begin
end.
Теперь после int достаточно одной звёздочки.
MrGalaxy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Dll и основная форма (взаимосвязь) fbus Работа с сетью в Delphi 9 16.04.2011 03:27
Основная программа и функция расположены в разных файлах. Марат05 C++ Builder 1 10.04.2011 19:05
Основная программа и функция расположены в разных файлах. Марат05 Общие вопросы C/C++ 1 01.04.2011 19:09
Движение кртинки туда сюда Fizerator Общие вопросы Delphi 5 09.02.2011 20:38
C++: 3 класса, + основная программа MR_Andrew Фриланс 13 22.04.2010 20:17