文章 "摆脱自制的 DLL" - 页 2

 

本文作者非常感谢能以如此通俗易懂的方式介绍不使用 自行车 dll 的 IPC 互操作性信息。

在我看来,使用内存的工作相当复杂,但除了一些问题外,方法还是很清晰的,希望有识之士能帮助理解:

1.在 memcpy 的帮助下,我们将一个两个字节的变量 short 复制到数组 uchar[2],那么这些信息是如何放入数组本身的呢?

uchar数组索引0和索引1处的值是什么格式?

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

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

值被逐字节分割并写入数组,好的 ...我想我明白了。

我不知道哪些值属于这个数组,也不知道如何从中获取原始值,问题不在于我不能在屏幕上显示这些值。


2.例如,在复制 memcpy 时,如何用不同类型的值正确填充 uchar[4]数组

uchar dst[4];
short src1 = 2;
short src2 = 13331;
memcpy(dst, src1, sizeof(src1));
memcpy(dst, src2, sizeof(src2)); // 改写一个已经存在的值,也就是说,我假定在写入 dst 时,必须在写入 src1 后指定偏移 2 字节的地址。

感觉答案很琐碎,一切都做得很简单,但如何正确书写呢?

 

您尝试过打印 吗?

 

第四个示例出现错误:'operator=' - 非法操作 使用 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; //   <----- Ошибка

}


我理解关于内存部分的想法,但也许定义不太正确?

能告诉我原因是什么吗?

非常感谢。
 
_SERG_:

内存位置的概念是清楚的,但也许在定义上有什么问题?

原因何在?

不同类型的结构不能再被复制,MQL 已经取消了这种可能性。

使用联合

//示例 4.通过 MQL 复制结构5
//---
struct str1
{
  double d; // 8 个字节
  long   l; // 8 个字节
  int i[3]; // 3 * 4 = 12 字节
};

//---
struct str2
{
  uchar c[ 8 + 8 + 12 ]; // 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 - 来自 s1 的字节数组
}
 
_SERG_:


顺便说一下,uchar 是错误的,double 也有可疑之处。

顺便说一下,src 应该说明它到底属于什么并将被传递。

有人已经按照你的建议纠正了你的错误。很好。想想吧。祝你好运

 
它对今天的 mql4 有用吗?
 
Seric29:
它现在能用于 MQL4 吗?

现在的语言(MQL4 / MQL5)完全相同--不同之处在于 MQL4 中缺少了 2-3 个函数(ArrayPrint 和其他一些小函数),而 MQL5 则增加了 "新功能"--数据库、DirectX 和 OpenCL。


但这篇文章是 8 年前写的,现在 MQL 已成为严格类型化的语言,要分配 2 个结构(文章中的示例),您需要编写一个复制构造函数或将结构序列化为字节数组,然后再返回。

 
Your article very big help to me, but how to copy the article did not mention a function pointer, because I need to put the callback function pointer passed as a parameter to the calling function. I don't know how to implement.
 
Example 4. Copying the structures by means of MQL5
struct str1
{
  double d; // 8 个字节
  long l;   // 8 个字节
  int i[3]; // 3*4=12 字节
};
struct str2
{
  uchar c[8+8+12]; // str1 结构大小
};
//+------------------------------------------------------------------+
//| 脚本程序启动功能|
//+------------------------------------------------------------------+
void OnStart()
{
  str1 src; 
  src.d=-1;
  src.l=20;
  //--- 填入结构参数
  ArrayInitialize(src.i, 0); 
  str2 dst;
  //--- 将结构转换为字节数组
  dst=src; 
}

为不同类型的结构体赋值已经行不通了 不允许参数 转换--需要相同类型的变量)。

但可以使用联合体:

struct str1
{
  double d; // 8 个字节
  long l;   // 8 个字节
  int i[3]; // 3*4=12 字节
};
struct str2
{
  uchar c[8+8+12]; // str1 结构大小
};
union union1
{
  str1 src;
  str2 dst;
};

//+------------------------------------------------------------------+
//| 脚本程序启动功能|
//+------------------------------------------------------------------+
void OnStart()
{
  union1 u; 
  u.src.d=-1;
  u.src.l=20;
  //--- 填入结构参数
  ArrayInitialize(u.src.i, 0); 

  //-- 表示结构的字节数组在 dst.c 中
  ArrayPrint(u.dst.c);
 
我想知道是否有可能获得指向函数的真正指针。使用 typedef 获得的指针在 mql 程序中运行得非常好。但不幸的是,我没能将它们传递给 dll。