記事"自作 DLL の排除"についてのディスカッション - ページ 2

 

この記事の著者は、自転車のDLL なしで IPCの相互運用性に関する情報をこのようにわかりやすく提示してくれたことに非常に感謝している。

メモリを扱うのはかなり複雑なように思えるが、いくつかの疑問点を除けばアプローチは明快である:

1.memcpyの助けを借りて、2バイトの変数shortを配列uchar[2]にコピーします

uchar配列のインデックス0と1の値はどのような形式になりますか?

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

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

値は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バイトのオフセットを指定してアドレスを指定しなければならないと仮定する。

答えは簡単で、すべてが単純に行われているように感じますが、どのようにそれを正しく書くのですか?

 

プリントを 試しましたか?

 

4番目の例ではエラーが発生します : 'operator=' - 不正な操作 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; //   <----- Ошибка

}


メモリ・セクションについての考え方は理解できましたが、定義が正しくないのでしょうか?

何が原因なのか教えてください。

よろしくお願いします。
 
_SERG_:

メモリーの位置という考え方は明確だが、定義に何か誤りがあるのでは?

理由は何だろう?

異なる型の構造体をコピーすることはできなくなった。

ユニオンを使う

//例4.MQL5による構造体のコピー
//---
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つの構造体を割り当てるには(記事の例)コピーコンストラクタを書くか、構造体をバイト配列に直列化し、また元に戻す必要がある。

 
あなたの記事は私にとって非常に大きな助けになりますが、私はとして渡されたコールバック関数のポインタを置く必要があるため、記事をコピーする方法は、 関数ポインタに 言及していませんでした。私は実装する方法がわからない。
 
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に渡すことができなかった。