Проблема передачи строк в импортируемые функции DLL от Delphi6

 

При передаче строки в DLL от DELPFHI6 в DLL не происходит ее чтения, подробнее:

1. при прописи переменной как (в DLL) PChar читается одна первая буква

2. при прописи как string - ничего не читается (1-байтовый символ)

3. при прописи как WideString(широкая строка) - выводит 3-8 символов (2-х байтовый символ)

С указателями ^ не совсем могу разобраться

4. как разобраться с этими пересылками строк и как прочитать, что передается в импортируемую программу (всяко не адрес, а первая буква по этому адресу)

5. при записи в файл один символ - 1-байт

6. какую строку передает MQL в импортируемые функции

7. если прописывать строку в первом параметре, невозможно прочитать все остальные

Пример. Для вывода управляющего модального окна надо прописать хотя бы его название (для вывода немодального - где получить дескриптор для синхронизации?, при вызове WinSight32 он не определяет дочерние окна в MQL, только дискриптор основной программы, если только через API ?)

Работа данного казуса - нажимаете любую клавишу на графике с советником с этим кодом(советнику должно быть разрешено торговать иначе событие OnChartEven не произойдет)-выводится модальное окно с редактируемыми входными переменными (с остановкой самой программы), выводится окно(не всегда поверх всех остальных) редактируете - во вкладке Эксперты -измененные значения(для дальнейшего использования)

Код в советнике MQL4

//--------------секция импорта---------------------------------------------------------------------------

#import "DllForm.dll"

double GetArrayValue(bool &arr[3],double lot,long l, int s, string &t);//buy,sell, lot,счет, период, инструмент

#import

//------------секция основного кода------------------------------------------------------------------------------------------

void OnChartEvent(const int id,

const long &lparam,

const double &dparam,

const string &sparam)

{

bool arr[3];

string t,s;

double lot;

int p;

long len;

if(id==CHARTEVENT_KEYDOWN)//любая клавиша

{

s =IntegerToString(lparam);

Print("код клавиши= ",s);

EventChartCustom(0,1,0,0,"Кнопка нажата");

//присвоение значений переменным

arr[0]=true; //произвольное значение для проверки

arr[1]=true; //произвольное значение для проверки

arr[2]=false; //произвольное значение для проверки

lot=3; //произвольное значение для проверки

len=AccountInfoInteger(ACCOUNT_LOGIN);//номер счета long

t= Symbol(); //string

p= Period(); //integer

Print(IntegerToString(len)+" "+t+" "+IntegerToString(p));

lot=NormalizeDouble(GetArrayValue(arr,lot, len, p, t ),2);// вызываем DLL

Print(arr[0],arr[1],arr[2], DoubleToStr(lot,2));//смотрим результат выполнения во вкладке эксперты

}

}

//------------------------------------------------------------------------------------------------

код в DLL (при повторении кода настроить свойства всех объектов (проще форму создать заново))

//-----------------------------------------------------------------------------------------------

unit DllFormU;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

CheckBox1: TCheckBox;

CheckBox2: TCheckBox;

CheckBox3: TCheckBox;

Button2: TButton;

ComboBox1: TComboBox;

Label1: TLabel;

private

{ Private declarations }

public

{ Public declarations }

end;

type aType=array[0..2] of boolean;

// входные параметры: массив переменных(разрешить-запретить продажу,покупку, сопровождение ордеров: BOOLEAN), объем лота, номер счета,период графика, символ инструмента

function GetArrayValue(var a:aType; lot:double; len:int64; s:integer ; t: WideString):double;stdcall;

var

Form1: TForm1;

implementation

{$R *.dfm}

function GetArrayValue(var a:aType; lot:double; len:int64; s:integer; t:WideString):double;

var

ss:string;

i:integer;

begin

ss:= IntToStr(len)+' '+IntToStr(s)+' '+t; //строка для заголовка

Form1:=TForm1.Create(Application);

Form1.CheckBox1.Checked:=a[0];//устанавливаем значение в поле sell, buy, close position при прорисовке окна управления

Form1.CheckBox2.Checked:=a[1];

Form1.CheckBox3.Checked:=a[2];

for i:=0 to 12 do

begin

if FloatToStrF(lot, ffFixed,2,2)=Form1.ComboBox1.Items.Strings[i] then //устанавливаем значение в поле объема ордера при прорисовке окна управления

Form1.ComboBox1.ItemIndex:=i ;

end;

Form1.Caption:=ss;

if Form1.ShowModal=mrCancel then

begin

result:=lot;

end

else

begin

a[0]:=Form1.CheckBox1.Checked; // получаем sell,buy, closeposition

a[1]:=Form1.CheckBox2.Checked;

a[2]:=Form1.CheckBox3.Checked;

result:=StrToFloat(Form1.ComboBox1.Items.Strings[Form1.ComboBox1.ItemIndex]);// получаем значение лота

end;

Form1.Free;

end;

end.

Данный код выводит в заголовок формы кроме второй половины инструмента (должно быть EURUSD выводит только EUR, дальше куда-то теряется)

Если кто-то сталкивался с этой проблемой, подскажите (вторую неделю не могу разобраться с этими строками), C++ как то не изучал, только примерно, DELPHI для меня понятней (хот шестой хоть десятый), потому-что у меня книжка есть (правда шестой). Задумка такая - ввести средство общения с работающим роботом посредством других языков программирования не прерывая самого вычислительного процесса.

компилированный код DLL во вложенном файле (Delphi 6)

Пример вызова :Модальное окно(не прописывается к EUR USD, т.е. переменная t= Symbol();

Модальное окно Delphi и MQL

 

Строки в DLL нужно ловить в структуру MqlStr, описание которой есть в MQL4\Scripts\Examples\DLL\DLLSample.cpp:

struct MqlStr
  {
   int               len;
   char             *string;
  };

Изучите примеры обработки аргументов в функциях этого файла.

 

// обьявление структуры данных 

 type
   TMqlString = Record
    size:integer;
    buffer: PWideChar;
    res: integer;
   end;

 //объявление массива типа структуры

 TMyArray2=Array[0..10] of TMqlString ; 

 procedure LoadData(var val:TMyArray2);  stdcall;

....



 // получение массива строк в dll из советника

procedure LoadData(var val:TMyArray2);  stdcall;

var k:integer;

 s:UnicodeString;

begin

 for k := 0 to i do   begin

  s:=StrPas(val[k].buffer); 

 ...

end; 

 

возврат делал стандартно через Result функции в виде PWideChar (одной строки)

вместо массива можно просто строку обьявить

 
harbor:

возврат делал стандартно через Result функции в виде PWideChar (одной строки)

вместо массива можно просто строку обьявить

Большое спасибо, т.к в DELPHI6 не нашел UnicodeString и для StrPas()PWideChar не подходит, немного сделал по другому

 var
    s:string;

 begin

  s:= WideCharToString(val[0].buffer);
  Form1.Caption:=s;
...

 end;

а вот в переменной size:integer непонятно, что за цифра передается, но всяко не количество символов(в принципе здесь роли не играет).

теперь и русские и нерусские передаются в заголовок формы:

модальное окно

Причина обращения: