blochの日記

自虐ネタ以外のぐちは書かないようにしましょう

頭脳ブルーカラー

VISA制御by Delphiメモ。dllをロードして、その中に隠されている各ルーチンのアドレスを、前もって確保して置いた同名の変数のアドレスに埋め込むのだ。埋め込むのだ!こっそり埋め込むのだ!
引数の順番を間違えないように、アドレス渡しと値渡しを間違えないように、あと、文字列の扱いは常に慎重に。DelphiからDLLへはstrcopy(buf,pchar(s))、但しbuf=packed array[0..2000]of char;、逆にDLLからDelphiへはcopy(string(buf),1,文字数); 死して屍拾う者なし。
では諸君、始めよう。

  1. ライブラリロード
    • var visa32lib:THandle;
    • visa32lib := LoadLibrary('VISA32.DLL')
      • visa32lib=0ならエラー
  2. viOpenDefaultRMの型定義
    • TviOpenDefaultRM=function(var dfltRM:ViSession):longword; stdcall;
    • 変数はポインタ渡し。【重要】visa.hとvisa32.basとで、一見記述が異なるように見えるので注意。BASIC表記では、値渡しの方に、Byvalと書いてある。C表記では、配列名はポインタであり、同じunsigned longでも、実はポインタだった(変数名にPが付いていたりする)ので、落ち着いて見ること。
      • ViSessionの型は明示されていないが、アジレントのマニュアルにunsigned longと書いてあった。
      • よって、Type ViSession=longword; としておく
      • 【後記】これは最初、なかなかわからず、とっかかりが掴めずに悩まされた。後で見ると、visatype.hの中に、typedef ViObject ViSession; と typedef ViUInt32 ViObject; がひっそりと書かれていることに気が付く。
  3. viOpenDefaultRMのアドレスを確保しておく
    • var viOpenDefaultRM: TviOpenDefaultRM;
  4. viOpenDefaultRMのアドレスゲット、そしてセット。
    • @viOpenDefaultRM:=GetProcAddress(visa32Lib,'viOpenDefaultRM');
      • 但し前もってvar viOpenDefaultRM: TviOpenDefaultRM; としておく
    • @viOpenDefaultRM=NILだとエラーが起きている。NILDelphiの定数
    • つまり、DLL内のprocedureを呼ぶには、Ⅰ.LoadLibraryでDLLをロードしハンドラゲット、Ⅱ.procedureの型定義、Ⅲ.変数としてアドレス確保、Ⅳ.GetProcAddressでアドレス確保、Ⅴ.変数にアドレスを格納
  5. viOpenDefaultRMの実行
    • stat:= viOpenDefaultRM(dfltRM);
    • dfltRMの型はViSessionと同じでlongword
      • ここが一番、不明瞭でどこにも書いていない。
  6. 各関数で値渡しとポインタ渡しを間違えると暴走する。

このあと、具体的に装置をオープンするviOpen、データを書き込むviWrite、読み込むviRead、、、、、殆ど肉体労働に近い。近いくせに終わった後の爽快感は無い。