- バックナンバー -1. OSLoadProgramを呼んでみるサンプル2. OSLoadProgramのサンプルを理解する3. C API はnnotes.dllから呼ばれている4. 参照渡しか値渡しか
さて、
LotusScriptから C API関数を呼ぶ話は興味がある方は興味を持って頂けると思うのですが、興味がない方には全然興味が無いと思うので、書いていて難しいのですが、書き始めてしまった以上こつこつ書いていこうと思います。
今日も引き続きAPI関数への変換の話をしようと思うのですが、
LotusScriptではあまり意識する事はありませんが、Cの関数では関数の引数として参照渡しと値渡しがあります。 値渡しであれば、関す内で引数をいくら書き換えても実行後戻ってきたときには引数の値は呼び出したときの値に戻っています。 参照渡しでは書き換えられた値を使用することが出来るのです。 言うまでもなく、
LotusScriptなどではすべて参照渡しで引数が処理されています。
ここを区別するにはデザイナーヘルプの「引数の参照渡しと値渡し 」なども参考にして頂きたいのですが、関数ごとにその引数が使われるかを考えなくてはいけません。単純にポインター引数か否か?と言うだけでは判断できない点もあるので都度よく考えるしかありませんが、実際的にはこの後とりあげる型変換の話と同じで、変換方法を覚えてしまう方法がいいかもしれません。
たとえば、C APIでは文書のIDとして、引数でそのまま渡せるNOTTEID (DWORD)が好んで使われます。このNOTEIDは値渡しされていることが多いのですが、関数の戻り値として引数にNOTEIDが使用される場合には参照渡しになるのでByValをつけることは出来ません。
また、C言語ではString型はchar型の配列を使用しますが、これは値渡しで使うことが多いように思えます。私自身はもうこれは例外ルールのような理解をしているのですが、デザイナーヘルプでは以下のように記載されています。
文字列を引き渡す
文字列が参照渡しされる場合、LotusScript は、文字列のコピーへの 4 バイトのポインタをメモリ内で割り当てられた内部バッファに渡します。LotusScript に C 関数が明確に記述されていない限り、C 関数はこのバッファの内容を安全に変更できません。
文字列が値渡しされる場合、LotusScript は、null で終わる文字列 (C 関数で想定されます) に 4 バイトのポインタを渡します。C 関数はこの文字列を変更できますが、その長さを伸ばすことはできません。文字列への変更は、関数からの戻り値としてスクリプトの変数に反映されます。文字列以外へのポインタを渡す場合は、パラメータを参照渡しします。
と言うわけで普通にNULLで終わる文字列を使う分には値渡しの事が多いのです。
OSLoadProgram() のサンプルでは以下のように宣言していました。
Declare Function OSLoadProgram
Lib "nnotes.dll" _ (Byval filename
As String, Byval FileDir
As String, Byval argv
As String, Byval flags
As Integer) As Integer Stringの部分は例によってすべてByVal を付けているのは上述したヘルプの記載に基づいています。
最後のFlagの部分は実はByValを付けなくても動いたのですが、C API リファレンスを見てもここはポインターでも何でもないWORD型の値を値渡ししているので、ByVal を付けた方がよいのではないかと思います。
上手く説明できていない部分も多いのですが、
LotusScriptではあまり意識しない引数の値渡し、参照渡しですが、C APIの呼び出しの際には慎重に考えていく必要があります。
最新コメント