Discussão do artigo "Eliminação de DLLs autogeradas" - página 2

 

O autor do artigo é muito grato por uma apresentação tão acessível de informações sobre a interoperabilidade de IPC sem dlls de bicicletas.

Trabalhar com a memória me parece um pouco complicado, mas a abordagem é clara, exceto por algumas perguntas que espero que pessoas com conhecimento ajudem a entender:

1. Com a ajuda do memcpy, copiamos uma variável short de dois bytes para a matriz uchar[2]. Como as informações são colocadas na própria matriz?

Em que formato estarão os valores nos índices 0 e 1 da matriz uchar?

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

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

O valor é dividido por byte por byte e gravado na matriz, ok... Acho que estou entendendo.

Não consigo entender quais valores entram nessa matriz e como obter o valor original a partir deles; a questão não é que eu não possa exibir esses valores na tela.


2. Como preencher corretamente a matriz uchar[4] com valores de tipos diferentes ao copiar memcpy, por exemplo:

uchar dst[4];
short src1 = 2;
short src2 = 13331;
memcpy(dst, src1, sizeof(src1));
memcpy(dst, src2, sizeof(src2)); // Sobrescreve um valor já existente, ou seja, presumo que, ao gravar em dst, o endereço deve ser especificado com um deslocamento de 2 bytes após a gravação de src1.

Parece que a resposta é trivial e tudo é feito de forma simples, mas como escrevê-la corretamente?

 

Você já experimentou oPrint?

 

O quarto exemplo apresenta o erro: '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; //   <----- Ошибка

}


Entendo a ideia sobre a seção de memória, mas talvez as definições não estejam corretas?

Você pode me dizer qual é o motivo?

Desde já, obrigado.
 
_SERG_:

A ideia de um local de memória é clara, mas talvez haja algo errado nas definições?

Qual é o motivo?

Estruturas de tipos diferentes não podem mais ser copiadas, o MQL removeu essa possibilidade.

usar união

/Exemplo 4. Cópia de estruturas por meio de MQL5
//---
struct str1
{
  double d; // 8 bytes
  long   l; // 8 bytes
  int i[3]; // 3 * 4 = 12 bytes
};

//---
struct str2
{
  uchar c[ 8 + 8 + 12 ]; // tamanho da estrutura 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 - matriz de bytes de s1
}
 
_SERG_:


uchar está errado, a propósito, e double também está presente de forma suspeita.

E, a propósito, src deve especificar o que exatamente pertence a ele e será passado.

Alguém já o corrigiu exatamente como você sugeriu. Muito bem. Pense nisso. Boa sorte.

 
Isso funcionará para o mql4 de hoje?
 
Seric29:
ele funcionará para mql4 hoje?

As linguagens (MQL4 / MQL5) são completamente iguais agora - a diferença está em 2-3 funções que faltam na MQL4(ArrayPrint e algo mais pequeno) e em "novos recursos" para a MQL5 - banco de dados, DirectX e OpenCL.


Mas o artigo foi escrito há 8 anos, agora a MQL se tornou uma linguagem estritamente tipada e, para atribuir duas estruturas (exemplo no artigo), você precisa escrever um construtor de cópia ou serializar a estrutura em uma matriz de bytes e, em seguida, retornar.

 
Seu artigo foi de grande ajuda para mim, mas como copiar o artigo não mencionou um ponteiro de função, pois preciso colocar o ponteiro da função de retorno de chamada passado como Não sei como implementar.
 
Example 4. Copying the structures by means of MQL5
struct str1
{
  double d; // 8 bytes
  long l;   // 8 bytes
  int i[3]; // 3*4=12 bytes
};
struct str2
{
  uchar c[8+8+12]; // tamanho da estrutura str1
};
//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
void OnStart()
{
  str1 src; 
  src.d=-1;
  src.l=20;
  //--- preenchendo os parâmetros da estrutura
  ArrayInitialize(src.i, 0); 
  str2 dst;
  //--- transformando a estrutura em uma matriz de bytes
  dst=src; 
}

A atribuição de structs de tipos diferentes não funciona mais( a conversãode parâmetros não é permitida - espera-se uma variável do mesmo tipo).

Mas seria possível trabalhar com uniões:

struct str1
{
  double d; // 8 bytes
  long l;   // 8 bytes
  int i[3]; // 3*4=12 bytes
};
struct str2
{
  uchar c[8+8+12]; // tamanho da estrutura str1
};
union union1
{
  str1 src;
  str2 dst;
};

//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
void OnStart()
{
  union1 u; 
  u.src.d=-1;
  u.src.l=20;
  //--- preenchendo os parâmetros da estrutura
  ArrayInitialize(u.src.i, 0); 

  //--- a matriz de bytes que representa a estrutura está em dst.c
  ArrayPrint(u.dst.c);
 
Gostaria de saber se é possível obter um ponteiro real para uma função. Os ponteiros obtidos usando typedef funcionam perfeitamente bem dentro do programa mql. Mas, infelizmente, não consegui passá-los para a dll.