Discussione sull’articolo "Sbarazzarsi delle DLL auto-prodotte" - pagina 2

 

L'autore dell'articolo è molto grato per la presentazione così accessibile di informazioni sull'interoperabilità IPC senza dll per biciclette.

Lavorare con la memoria mi sembra piuttosto complicato, ma l'approccio è chiaro, tranne che per alcune domande, che spero le persone competenti aiuteranno a capire:

1. Con l'aiuto di memcpy copiamo una variabile short a due byte nell'array uchar[2], come vengono inserite le informazioni nell'array stesso?

In che formato saranno i valori agli indici 0 e 1 dell'array uchar?

uchar dst[2];
short src = 13331;
memcpy(dst, src, sizeof(src));

uchar[0] = ?, uchar[1] = ?;

Il valore viene diviso byte per byte e scritto nell'array, ok... Credo di aver capito.

Non riesco a capire quali valori rientrano in questo array e come ottenere il valore originale da essi, il problema non è che non posso visualizzare questi valori sullo schermo.


2. Come riempire correttamente l'array uchar[4] con valori di tipo diverso durante la copia di memcpy, per esempio:

uchar dst[4];
short src1 = 2;
short src2 = 13331;
memcpy(dst, src1, sizeof(src1));
memcpy(dst, src2, sizeof(src2)); // Sovrascrive un valore già esistente, cioè presumo che quando si scrive su dst, l'indirizzo debba essere specificato con un offset di 2 byte dopo la scrittura di src1.

Sembra che la risposta sia banale e che tutto sia fatto in modo semplice, ma come scriverlo correttamente?

 

Avete provato astampare?

 

Il quarto esempio dà errore: 'operator=' - illegal operation use SAMPLE_04.mq4 34 7

#property copyright ""

#property link      ""

#property version   ""

#property strict

//Пример 4. Копирование структур средствами MQL5

//---

struct str1

{

  double d; // 8 байт

  long   l; // 8 байт

  int i[3]; // 3 * 4 = 12 байт

};

//---

struct str2

{

  uchar c[ 8 + 8 + 12 ]; // размер структуры str1

};

//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart(){

  str1 src;   // 

  src.d = -1; // 

  src.l = 20; //

  //--- заполняем параметры структуры

  ArrayInitialize(src.i, 0); 

  str2 dst;  //  

  //--- превратили структуру в байтовый массив

  dst = src; //   <----- Ошибка

}


Capisco l'idea della sezione di memoria, ma forse le definizioni non sono corrette?

Potete dirmi qual è il motivo?

Grazie in anticipo.
 
_SERG_:

L'idea di una posizione di memoria è chiara, ma forse c'è qualcosa di sbagliato nelle definizioni?

Qual è il motivo?

Le strutture di tipo diverso non possono più essere copiate, MQL ha eliminato questa possibilità.

utilizzare l'unione

//Esempio 4. Copia di strutture tramite MQL5
//---
struct str1
{
  double d; // 8 byte
  long   l; // 8 byte
  int i[3]; // 3 * 4 = 12 byte
};

//---
struct str2
{
  uchar c[ 8 + 8 + 12 ]; // dimensione della struttura str1
};

union str12 { str1 s1; str2 s2; };

//------------------------------------------------------------------
void OnStart()
{
  str12 src;
  src.s1.d = -1; // 
  src.s1.l = 20; //
  ArrayInitialize(src.s1.i, 0); 

  // src.s2 - array di byte da s1
}
 
_SERG_:


uchar è sbagliato e anche double è presente in modo sospetto.

E comunque src dovrebbe specificare cosa gli appartiene esattamente e cosa gli verrà passato.

Qualcuno ti ha già corretto come hai suggerito. Bene. Pensate. Buona fortuna.

 
funzionerà per mql4 per oggi?
 
Seric29:
funzionerà per mql4 oggi?

I linguaggi (MQL4 / MQL5) sono completamente uguali - la differenza è in 2-3 funzioni mancanti in MQL4(ArrayPrint e qualcos'altro di piccolo) e in "nuove caratteristiche" per MQL5 - database, DirectX e OpenCL.


Ma l'articolo è stato scritto 8 anni fa, ora MQL è diventato un linguaggio strettamente tipizzato e per assegnare 2 strutture (esempio nell'articolo) è necessario scrivere un costruttore di copia o serializzare la struttura in un array di byte e poi di nuovo.

 
Il tuo articolo molto grande aiuto a me, ma come copiare l'articolo non ha menzionato un puntatore di funzione, perché ho bisogno di mettere il puntatore di funzione di callback passato come Non so come implementare.
 
Example 4. Copying the structures by means of MQL5
struct str1
{
  double d; // 8 byte
  long l;   // 8 byte
  int i[3]; // 3*4=12 byte
};
struct str2
{
  uchar c[8+8+12]; // dimensione della struttura str1
};
//+------------------------------------------------------------------+
//| Funzione di avvio del programma di script|
//+------------------------------------------------------------------+
void OnStart()
{
  str1 src; 
  src.d=-1;
  src.l=20;
  //--- riempimento dei parametri della struttura
  ArrayInitialize(src.i, 0); 
  str2 dst;
  //--- trasformando la struttura in un array di byte
  dst=src; 
}

L'assegnazione di strutture di tipo diverso non funziona più(la conversionedei parametri non è consentita - ci si aspetta una variabile dello stesso tipo).

Ma sarebbe possibile lavorare con le unioni:

struct str1
{
  double d; // 8 byte
  long l;   // 8 byte
  int i[3]; // 3*4=12 byte
};
struct str2
{
  uchar c[8+8+12]; // dimensione della struttura str1
};
union union1
{
  str1 src;
  str2 dst;
};

//+------------------------------------------------------------------+
//| Funzione di avvio del programma di script|
//+------------------------------------------------------------------+
void OnStart()
{
  union1 u; 
  u.src.d=-1;
  u.src.l=20;
  //--- riempimento dei parametri della struttura
  ArrayInitialize(u.src.i, 0); 

  //--- l'array di byte che rappresenta la struttura è in dst.c
  ArrayPrint(u.dst.c);
 
Mi chiedo se sia possibile ottenere un vero puntatore a una funzione. I puntatori ottenuti tramite typedef funzionano perfettamente all'interno del programma mql. Ma purtroppo non sono riuscito a passarli alla dll.