System4.0 Tips

 

 

System4.0 DLL開発用テンプレート

 


 注意

 動作無保証。

 ポインタ操作をバリバリ行ってますので、動作不安定になっても責任は持てません。上級者向き。

 

これは何?

 System4.0で動作するDLL( C++で作成する )を製作するのを補助します。

 HLLを作成するのに面倒なところは、配列や構造体を渡されたときの処理です。
DLLは、IVMArray2* や、IVMStruct3* で受け取って、そのインタフェースの関数を経由して、
処理を行わなければなりません。ですが、いちいちGetDataしてキャストして、を繰り返すのは、
単調で面倒だなぁ…と思いませんか?

 この開発用テンプレートを用いれば、配列をstd::vectorのように扱えますし、
構造体にポインタ参照( -> )でアクセスできるようになります。

 

テンプレートを見てみる

※ 必要十分なテストを行っていません。問題があったら連絡下さい。

 

 

配列のサンプル

 

System4.0 HLL呼び出し規約


// TemplateTest1.hll ver1.00

void ArrayTest(ref array@int ar1,ref array@string ar2);

 

配列は、ref付で渡すと、DLLによる変更が反映されます。

 

System4.0 ソースコード


 array@int  Array1;
 array@string Array2;

 Array1.Alloc(3);
 Array2.Alloc(3);

 Array1[0]=1001;
 Array1[1]=1002;
 Array1[2]=1003;

 Array2[0]="This is test.";
 Array2[1]="これはテストです";
 Array2[2]="本日は晴天なり。";

 TemplateTest1.ArrayTest(Array1,Array2);

 int i;
 for(i=0;i<Array1.Numof();i++){
   system.Output("Array1[%d]=%d\n" % i % Array1[i]);
 }
 for(i=0;i<Array2.Numof();i++){
   system.Output("Array2[%d]=%s\n" % i % Array2[i]);
 }

 

適当に代入して、DLL呼んで、出力しています。

 

DLLソース (C++)


#include "s40strc.h"

//適当にincludeする。

 


#define DLLEXPORT __declspec(dllexport)
extern "C" DLLEXPORT void ArrayTest(IVMArray2* ar1,IVMArray2* ar2);

 

void ArrayTest(IVMArray2* ar1,IVMArray2* ar2){

    s4Array<int> Array1(ar1);
    s4Array<string> Array2(ar2);

    // 参照と編集
    for(int i=0;i<Array1->size();i++){
         Array1[i]=Array1[i] * i;
    }
    // 追加も自由。
    Array1->push_back(65536);
 

    // 文字列は、std::stringなので、こんなことができます。
    Array2[0]=Array2[0]+"を訳すと" + Array2[1] + "になります。";

    // 文字列配列を追加することも簡単。
    Array2->push_back("今日はよい天気です。");
    Array2->push_back("明日もよい天気です。");

}

 

s4Arrayをかぶせると、vectorの代わりみたいに用いれます。
vectorのメンバ関数( size()とかpush_back()とか )を呼ぶには、ポインタ参照( -> )で。
stringの場合は、std::stringで操作できるので、楽チンです。

多次元配列には対応していません。

 

構造体のサンプル

 

System4.0 HLL呼び出し規約


// TemplateTest2.hll ver1.00

void StructTest(ref TempTest1_t st1);

 

配列は、ref付で渡すと、DLLによる変更が反映されます。

 

System4.0 ソースコード

// 構造体の定義

struct TempTest1_t{
       int num1;
       string str1;
       float flo1;
       array@int Array1;
};
 


 TempTest1_t test;
 test.num1=100;
 test.str1="テスト";
 test.flo1=0.5f;
 test.Array1.PushBack(1);
 test.Array1.PushBack(2);

 TemplateTest2.StructTest(test);

 system.Output("num1=%d\nstr1=%s\nflo1=%f\n" % test.num1 % test.str1 % test.flo1);
 int i;
 for(i=0;i<test.Array1.Numof();i++){
   system.Output("Array1[%d]=%s\n" % i % test.Array1[i]);
 }

 

適当に代入して、DLL呼んで、出力しています。

 

DLLソース (C++)


#include "s40strc.h"

//適当にincludeする。

 


#define DLLEXPORT __declspec(dllexport)
extern "C" DLLEXPORT void StructTest(IVMStruct3 * st1);

//////////////////////////
// 利用する構造体を囲む //

#pragma pack(push,1)

struct TempStruct_t{
       int num1;
       string str1;
       float flo1;
       s4Array<int> Array1;
};

#pragma pack(pop)
// 利用する構造体を囲む //
//////////////////////////

void StructTest(IVMStruct3 * st1){

    s4Struct<TempStruct_t> Struct1(st1);

    // -> をつかって、適当にいじくれます。
    Struct1->num1=Struct1->num1*Struct1->flo1;
    Struct1->str1=Struct1->str1+"です。";
    Struct1->Array1[0]=Struct1->Array1[0]+Struct1->Array1[1];
    Struct1->Array1->push_back(100);
    Struct1->Array1->push_back(200);
    Struct1->Array1->push_back(300);
}

 

s4Structをかぶせると、ポインタ参照( -> )で操作できます。
注意事項としては、C++のソースの、色違いの部分。
つまり、System4.0で定義した構造体とまったく同じ構造体を記述し、なおかつ、#pragma packで括らないといけない。

構造体に記述する型は、以下のようになります。

System4.0 C++
  int   int
  string   std::string
  float   float
  bool   bool
  array@int   s4Array<int>
  array@string   s4Array<std::string>
  array@float   s4Array<float>
  array@bool   s4Array<bool>
  struct   IVMStruct3*
  array@struct   s4Array<IVMStruct3*>
  ref int   使用できません

System4.0において、構造体の中の構造体は、構造体の定義に
s4Structを使えません。IVMStruct3* で定義してください。
使用する関数の中で、s4Struct<...>で括って使用してください。

また、ref intをはじめとする、すべての参照オブジェクトは使用できません。
これは、System4.0から参照オブジェクトを取得する方法が、
デバッグプラグインを除いて、存在しないためです。

 

 

もうちょっと細かく説明

  テンプレートでくくると、データがSystem4.0からすべてコピーされます。
  デストラクタが呼ばれると、データがSystem4.0にコピーされます。
  そんな風にできています。

  System4.0のHLLにrefをつけないといけないのは、
  つけないと、DLLでの変更が更新されないからです。
  読み込みだけでいいや、ってときは、HLLにrefをつけない上に、
  s4Arrayやs4Structの第二引数に、trueを渡してください。
  デストラクタでコピーしなくなるので、少し早くなるはずです。

 

 感想

 非常に悪いテンプレートの見本みたいなものです。
大変怪しげな実装を施してあると思います。
C++は専門じゃないんで、よくわからないんですけど。

 そして、これは、ちょっと…恐ろしいプログラムです。
構造体に変数を追加すれば暴走、順番が変われば暴走。
そんな可能性のある素敵なプログラムです。

 でも、ものすごく便利です。