OSLoadProgramを呼んでみる

2009年10月06日 00:37

- バックナンバー -
1. OSLoadProgramを呼んでみるサンプル
2. OSLoadProgramのサンプルを理解する
3. C API はnnotes.dllから呼ばれている
4. 参照渡しか値渡しか
5. 型を変換する
6. 構造体を定義する
7. OSLoadString を使ってみよう

さて、LotusScript では外部DLLの関数を呼ぶ事が出来る事はご存知でしょうか。

そこで、まずはNotesのC API関数であるOSLoadProgramを呼ぶサンプルをチュートリアル代わりに書いておきます。 C:\temp フォルダにある newfile.txt をノートパッドで開くサンプルです。


Declare Function OSLoadProgram Lib "nnotes.dll" _
(Byval filename As String, Byval FileDir As String, Byval argv As String, flags As Integer) As Integer

Sub Click(Source As Button)
Call OSLoadProgram ("c:\windows\notepad.exe", "c:\temp", "newfile.txt",0)
End Sub

This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.


LotusScript に明るい方ならこのサンプルに実用的な意味がほとんどないことにすぐ気が付くと思います。別にShell関数でこのくらい出来ますよね。
単純にLotusScriptからAPIを呼ぶ事が出来る、と言う事を技術的に示しただけです。

色々話す前にサポート的なことを言っておくと、サポートの観点ではAPI関数を呼んで必要な機能を実現するなアプリケーションは可能な限り避けた方がいいと思います。極端な話を言えば、たとえやり方を知らなくても、APIを呼ばなければ出来ないような事はやらない、と言う姿勢は間違ってない気がします。
 他にもPortabilityの問題も考えなくてはいけません。 同じ要領でW32 APIを呼ぶ事も出来ますが、たとえばXPとVistaと2000で同じ動きをするのか分からなくなったりしますし、本来NSFファイルはどのプラットフォームのドミノでも動かせますがこのような処理が入っていると、Windows用に書いたら各プラットフォーム用にDLLとかライブラリ名を変えないといけないので書き換えないといけません。
(この辺はもちろんテクニックがありますが。)
 更に言うとAPIを直接呼ぶ場合には間違って呼べばLotusScriptのようにランタイムエラーでは済まないのですぐクラッシュしてしまいます。この辺はとにかくクラッシュさせるのはそのDLLがおかしい、と考える人もいますが、事実Notes に限らず、他の言語でも API関数を直接呼ぶ場合はほとんどの場合そうなってしまうので、これは呼び出し側が気をつけるしかありません。
LotusScriptの下位互換性も呼び出したAPIに対しては保証できないので、マイグレーション時も特に気をつける必要があります。

と言うわけで今日のところは導入だけでこれから少しずつどういう風にAPI関数を呼び出していくのか紹介していこうと思います。

ちょっと変わったネタなのですが、興味を持った方は拍手でもお願いします。
反応薄かったらあと1,2回くらいで一段落つくので、止めておきます。

OSLoadProgramのサンプルを理解する

2009年10月14日 00:50

- バックナンバー -
1. OSLoadProgramを呼んでみるサンプル
2. OSLoadProgramのサンプルを理解する
3. C API はnnotes.dllから呼ばれている
4. 参照渡しか値渡しか
5. 型を変換する
6. 構造体を定義する
7. OSLoadString を使ってみよう

 さて、前回のOSLoadProgramのサンプルの記事ではたくさんの拍手を頂きありがとうございました。
間が空いてしまって申し訳なかったのですが、今日は始めのトピックとして前回のサンプルを呪文のように実行してしまったのでもう少し意味が分かるように考えてみる事にします。(これもゆっくり連載したいので何回かに分けて紹介しようと思います。) LotusScript からNotesの C API を呼ぶ、ということがどういうことなのか少し分かってくるのではないかと思います。この辺を踏まえて、実際に自分で色々呼べるようになるのはもう少し先になるのではないかと思うのでご容赦下さい。

 はじめに少しでもこの記事を通じてLotus Notes/Domino C API を勉強しようと思っている方は、以下のページからToolkitをダウンロードしておいていいのではないかと思います。
 コンパイルまでする気が無くても、別にインストール作業は必要ないですし、サンプルやリファレンスが入手できるだけでも面白いのではないかと思います。

Lotus C API Toolkit Download Page (Search)

その前に、このブログを読むのに必要な情報だけでいいなら以下のリファレンスページをダウンロードしておくだけでもいいのではないかと思います。
Lotus C API 7.0 Reference for Domino and Notes

それでは、始めに基本中の基本として、OSLoadProgramとはどういうAPI なのか考えてみる事にします。
ヘルプの記載を見てみましょう。

C API リファレンスより
STATUS LNPUBLIC OSLoadProgram(
char far *filename,
char far *WorkingDir,
char far *Arguments,
WORD Flags);

Description :
This function loads and executes an external Program. Use OSLoadProgram to load and execute software modules at run time.

OSLoadProgram provides C API programs with a platform-independent procedure for loading and executing a program.

Starting with Release 4.6, the command line is assumed to be in LMBCS, the Lotus Multi-Byte Character Set, and is translated to the operating system's native character set before being passed to the called program.


今更ヘルプの読み方的な話をするのは多少失礼になる方もいると思うのですが、引数・戻り値の説明を理解するのは、LotusScriptなどと同じなのですが、関数のインターフェース(戻り値とか引数の型の事)を理解する事が非常に重要になります。C言語が分からない方にはちょっと読みにくく感じるかもしれません。

 STATUSというのは何の呪文だろうと思うかも知れませんが、これもAPI リファレンスの記述を見ると、

typedef WORD STATUS;

となっているので、要はWORD型であることが分かります。
同様にして分かりにくい、LNPUBLICについても調べてみると、Notes C API 関数の Calling Convention と書かれていますが、要するに外部から呼び出し可能なAPIについているおまじないのようなものだと理解してもらえれば十分なのではないかと思います。 Lotus Notes Public Function、みたいなノリなのではないでしょうか。

ちなみにOSLoadProgram というのはここでも記載のある通り、Notes でプログラムを実行するためのAPIですが、Notesでは内部的にも非常によく使われることが多いものです。
もっとも典型的な使用例では、サーバー起動時にNotes.ini 行にServerTasks行に書いてある順にタスクが起動させられていますが、ここでタスクを起動する際に使用されているAPIはOSLoadProgram です。

ちなみにこの辺の詳細情報を取得する際には、Notes/Domino 7 以降では、DEBUGSIGCIHLD=1 をNotes.iniに指定します。(それ以前のリリースでは、UNIX版のみ)
元々はこの設定は、その名の通り、SIGCHLD (または SIGCHILD)の情報を取得するために使われていたのですが、実は起動時の情報も必要なのでこの設定によって記録されます。

それと、OSLoadProgramをサンプルに選んだ理由ですが、APIを一つ呼ぶだけで処理が完結するいわゆる「呼び出しやすい」例だったからです。
 「LotusScriptから C APIを呼び出せる」と言う言葉を聞いて、C APIの関数はすべてLotusScriptで呼べるような誤解をする人がいますが、関数ポインタやコールバック関数など技術的にLotusScriptでは表現不能なものもあるので、注意が必要です。(実はVBではこの辺をある程度補完してくれる関数もあるので、VBには移植可能だったけど、LotusScriptでは出来ない、と言う事もあります。)
と言うわけで C API の呼び出しに関しては、これから紹介する話で機械的な変換方法が分かる、と言うような簡単なものではなく、

・ 簡単に呼べる
・ 技術的には呼べるようだが、実際にはかなり大変
・ 技術的に呼ぶことが出来ない

ものがあり、事前にその辺を十分に評価していないと実際には出来ない処理を出来ると言って逃げ道をなくしてしまうことにもなるので気をつけてください。

まだ物足りないと思いますが、今日はヘルプを入手して、関数の情報を確認する、と言う話までやりました。 次は具体的な呼び出しについてもう少し見ていきます。



C API はnnotes.dllから呼ばれている

2009年11月02日 00:19

- バックナンバー -
1. OSLoadProgramを呼んでみるサンプル
2. OSLoadProgramのサンプルを理解する
3. C API はnnotes.dllから呼ばれている
4. 参照渡しか値渡しか
5. 型を変換する
6. 構造体を定義する
7. OSLoadString を使ってみよう
そろそろ8.5.1を使う予定がない人は8.5.1の新機能紹介の記事に飽きてきているかもしれないので、今日は通常の記事に戻っていきたいと思います。

さて、LotusScriptからC APIを呼ぶ方法ですが、前回はサンプルで読んだ「OSLoadProgram」のようにC APIの関数を呼ぶためにはまずC APIのリファレンスを入手する必要がある旨を説明しました。

Declare Function OSLoadProgram Lib "nnotes.dll" _
(Byval filename As String, Byval FileDir As String, Byval argv As String, flags As Integer) As Integer

LotusScriptでは外部DLLから関数を呼び出すときには、呼び出したい関数名(上の例ではOSLoadProgram)に加えてLib ステートメントでどのDLLから呼び出すかを宣言しないといけません。
サンプルではnnotes.dllから呼び出されていましたが、C API関数はどのようにしてDLLを調べればいいのでしょうか?

実はNotesのC API関数の場合、この点については悩む必要がありません。
Notes が使用しているDLLファイルは無数にありますが、C API関数として公開されているものは、Windowsプラットフォームであれば、全て nnotes.dllから呼び出されたものです。サーバーもクライアントも、NotesとDominoのコアと言えるデータベースやビューに関する処理はほとんどnnotes.dll でまかなわれているのです。

ただし、プラットフォームが違う場合は、名前が変わるのでバリエーションについては覚えておく必要があります。AIXであれば、libnotes_r.a、SolarisやLinuxであれば、libnotes.so のようなライブラリがnnotes.dllと等価のファイルになります。

詳細については以下の文書も参考にしてください。(OS/2が Inotes.dll、と言う事などは知りませんでした・・・)

What is the equivalent of nnotes.dll (W32) on a Unix system

まだ宣言文の説明も終わってない!と思う方も多いと思うのですが、引数や戻り値の型変換が説明として一番ややこしいのでその辺を後回しにしているうちにこんな感じになってしまっているので今しばらくお待ち下さい。。。

LS2CAPI : 参照渡しか値渡しか

2009年11月20日 03:15

- バックナンバー -
1. OSLoadProgramを呼んでみるサンプル
2. OSLoadProgramのサンプルを理解する
3. C API はnnotes.dllから呼ばれている
4. 参照渡しか値渡しか
5. 型を変換する
6. 構造体を定義する
7. OSLoadString を使ってみよう


 さて、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の呼び出しの際には慎重に考えていく必要があります。





LS2CAPI: 型を変換する

2009年12月09日 00:04

- バックナンバー -
1. OSLoadProgramを呼んでみるサンプル
2. OSLoadProgramのサンプルを理解する
3. C API はnnotes.dllから呼ばれている
4. 参照渡しか値渡しか
5. 型を変換する
6. 構造体を定義する
7. OSLoadString を使ってみよう

 C API 関数を呼び出す上で次に必要になるのはC言語での型からLotusScriptの型に変換する方法です。
先に結論から言ってしまうと、実際的には以下のようなサイトから変換表を借りるのが一番省エネな方法なのではないかと思います。

Translating API Data Types to LotusScript (nsftools)

ただ、一度どのようにこれらの変換を考えるかはゆっくり精査してみるといいと思います。
たとえば、ここの表を見ると、Windows などでよく使われるDWORD型はLotusScriptではLong型に対応付けられています。

DWORD というのは一般的には unsigned long なので、 0 ? 4294967295 までの数を表します。
LotusScriptでのLongデータ型は、 -2,147,483,648 以上 2,147,483,647 以下の整数なので厳密にはマッチしません。
ただ、デザイナーヘルプをよく見てみると、「引数を C 関数へ引き渡す」と言う項にLongデータ型はC関数に渡すときに「4 バイトの Long 型の値が呼び出しスタックに push されます」とあるので、LotusScriptのLong型はマイナス値を渡したときの振る舞いはよく分からないですが、正の値を渡している場合には4バイトの数として扱ってくれるようです。一般的にはNotesに限らずAPI呼び出しなどを行う場合にこのようなことをするとクラッシュしてしまいます。
 この辺については色々理屈にこだわるより慣習に従った方がいいのではないかと思います。。

あとはたとえばC APIでは「STATUS型」などを関数の戻り値にしているのをよく見かけます。
こういうのを見かけたら、API リファレンスを探してみましょう。ちゃんと「STATUS」と言う項目に以下のような説明があるのが分かります。

Definition :
typedef WORD STATUS;

つまり、これは WORD型 = unsigned short と同じ、Integer型になっているのが分かると思います。
と言うわけで型変換は毎回一からやっているととても大変なのでこのようなものは書き溜めておくと便利なのではないかと思います。

また、LotusScriptの型はC 言語ほど豊富ではないのでLotusScriptからC API関数を呼び出すことはある程度技術的にも限界があることなんだ、と言う事は念頭に入れた上で挑戦してみたほうがよいと思います。
ブロガーの方が試行錯誤した上で色々な型変換の表を色々なところで公開してもらえると楽しそうですよね。

LS2CAPI: 構造体を定義する

2009年12月16日 00:04

- バックナンバー -
1. OSLoadProgramを呼んでみるサンプル
2. OSLoadProgramのサンプルを理解する
3. C API はnnotes.dllから呼ばれている
4. 参照渡しか値渡しか
5. 型を変換する
6. 構造体を定義する
7. OSLoadString を使ってみよう


C APIやC言語の関数をLotusScriptで扱うに当たって、構造体をどのように扱うのか不思議に思う方は多いのではないでしょうか。今日はその点について取り上げてみようと思います。

例として、NotesのTIMEDATE型を例にとって見ましょう。
NotesのTIMEDATE型はDBIDやOIDの一部になっていたり、Notesの時間の扱いを理解する上でも非常に重要な型の一つですが、LotusScriptNotesTIMEDATEクラスでもIDのまま見ることはできないのでなかなか分かりにくい事が多いのですが、APIで時間を扱うときはほとんどこの型で処理されます。このIDについてしゃべると長いので別の機会にするとして、どのようなデータ型なのでしょうか?始めに、C API リファレンスで定義を見てみましょう。
TIMEDATEという項目を見ると以下のように定義されているのが分かります。

Definition :
typedef struct tagTIMEDATE {
DWORD Innards[2];
} TIMEDATE;


つまり、TIMEDATE型は、DWORD型の配列である事が分かります。DWORD 型は前回の記事を見るとLong型であることが分かるので、LotusScriptではLong型の配列とすればよさそうです。

LotusScriptでは構造体はユーザー定義型としてマッピングするのですが、ユーザー定義型を宣言するときには、TYPEステートメントを使用します。この辺はVBなどを知っている方の方が聞きなれているかもしれません。

つまり、TIMEDATE型はLotusScript以下のように定義できる事が分かります。
TIMEDATE
Innards(0 To 1) As Long
End Type



ただ、実際は構造体の変換は構造体の中に構造体があったり、関数ポインターを扱っていたりもっともっと複雑なので、何でもLotusScriptに変換できるわけではないので、変換できないこともあると思いますし、機械的に出来るわけではないと思います。

せっかくなので、今日の例を生かして、NotesのC APIで現在の時間を返すOSCurrentTIMEDATEを呼び出してみましょう。時刻はNotesのTIMEDATE型で帰ってくるので見た目は時間である事が分からないので実用性はあまりないと思いますが、どんなAPIなのかは概要がつかめるのではないかと思います。出てくる数字もよくDBIDやUNIDで見かけるような数字の並びになっていることに気が付くのではないかと思います。
サンプルで気をつけて欲しいのは、UIで表示されている順番と、配列の順番が逆になっている事です。

サンプルコード(ボタンスクリプト)
Type TIMEDATE
Innards(0 To 1) As Long
End Type

Declare Sub OSCurrentTIMEDATE Lib "nnotes.dll" (retTime As TIMEDATE)

Sub Click(Source As Button)
Dim curTime As TIMEDATE
Call OSCurrentTIMEDATE(curTime)

' 時刻IDの表示
Msgbox Hex(curTime.Innards(1)) & ":" & Hex(curTime.Innards(0))
End Sub

OSLoadString を使ってみよう

2010年03月21日 23:05

今日はC APIのサンプルとして、OSLoadString を使用したサンプルを呼んでみましょう。
過去の記事が参照したい方は以下のバックナンバーを見てみて下さい。


- バックナンバー -
1. OSLoadProgramを呼んでみるサンプル
2. OSLoadProgramのサンプルを理解する
3. C API はnnotes.dllから呼ばれている
4. 参照渡しか値渡しか
5. 型を変換する
6. 構造体を定義する
7. OSLoadString を使ってみよう

 以前にこのブログでも、Notesのエラーコードからエラーメッセージを得る方法として、Show Messageコマンドを使用して確認する方法を、この記事で紹介しましたが、このようにエラーメッセージからエラーコードを取得する場合、内部的にはOSLoadStringを呼び出します。

宣言などの詳細は今までと同じ考え方なので、C API のリファレンスを見て頂ければ分かると思いますが、今回は固定長のStringを扱うために、「String*256」のように宣言しています。エラーメッセージが必ずしも256文字で収まるとは限らないのですが、このようにして文字列の大きさがあいまいになるのを防いでいます。APIを呼び出す場合はこのような点は過剰なくらいに対応しておかないとすぐに不安定になってしまうので十分に気をつけてください。

次にエラーコードは、余計な値が含まれている場合があるので値をマスクする必要があるのですが、これはC APIでは、ERR() と言うマクロが用意されています。

#define ERR(x) ((STATUS) (x & ERR_MASK))

この処理をエミュレートするために、GetAPIError では以下の処理が加わっています。

MaskedErrCode = errCode And ERR_MASK


単体関数を呼び出す、と言う意味ではあまり進歩の無い例に見えるかも知れないですが,OSLoadString はAPIのエラーをハンドルする場合には必ず必要があるので、使用頻度は意外と高いのではないかと思います。


Declare Function OSLoadString Lib "nnotes.dll" (Byval hModule As Long, Byval StringCode As Long, Byval retBuffer As String, Byval BufferLength As Integer) As Integer
Const ERR_MASK = &H3fff

Sub Click(Source As Button)
HexErr = Inputbox("エラーコードを16進数で入力してください 例: 1A5")
errCode = Val("&H" & HexErr)
Msgbox GetAPIError(Str(errCode))
End Sub

Function GetAPIError(errCode As String) As String
Dim retBuffer As String*256
Dim Buflen As Integer
Dim ErrMsgLen As Integer
Dim StringLen As Long
Dim MaskedErrCode As Long
Dim resultStringLength As Integer

ErrMsgLen = OSLoadString(0, StringCode , retBuffer, Len(retBuffer)-1)
MaskedErrCode = errCode And ERR_MASK
resultStringLength = OSLoadString(0, MaskedErrCode, retBuffer, Len(retBuffer) - 1)
GetAPIError = retBuffer
End Function


以下の記事も参考にしてみてください。

OSLoadString を LotusScript から Call してみよう (Lunatic Sol)
Translating Notes API Errors (nsftools)

OSの違いを吸収する

2011年02月13日 02:15

- バックナンバー -
1. OSLoadProgramを呼んでみるサンプル
2. OSLoadProgramのサンプルを理解する
3. C API はnnotes.dllから呼ばれている
4. 参照渡しか値渡しか
5. 型を変換する
6. 構造体を定義する
7. OSLoadString を使ってみよう
8. OSの違いを吸収する

しばらく書いていませんでしたが、ちょっと書こうと思っていた記事があったのを思い出しました。
LotusScriptからC APIを呼び出すようなプログラムをノーツアプリケーションに移植すると一気に移植性が損なわれてしまう、と思った方はいないでしょうか?

このように書くと、nnotes.dllはWindowsのDLL名なので、その関数はWindowsでしか使えなくなってしまいます。
Declare Function NSFDbOpen Lib "nnotes.dll" ( _
Byval PathName As String, rethDB As Integer ) As Integer


しかもLib宣言はif文で分けるようなことはできません。
このような問題はどのように回避するのでしょうか?

ちょっとこのような問題をどう解決するのかを見ていくために、DJX管理ツールを見てみましょう。
ここではユーザー登録などをノーツアプリケーションから実行するために一部APIを使用しています。

APIFunctionsDef と言うスクリプトライブラリでは以下のように宣言されています。
(一部抜粋)

'###################################
' Declarations of Notes C API functions
'###################################
Const LIBNAME_WIN = "nnotes.dll"
Const LIBNAME_ALP = "anotes.dll"
Const LIBNAME_OS2 = "inotes.dll"
Const LIBNAME_SOL = "libnotes.so"
Const LIBNAME_AIX = "libnotes_r.a"
Const LIBNAME_OS400 = "/qsys.lib/qnotes.lib/libnotes.srvpgm"
Const LIBNAME_LINUX = "libnotes.so"
//略
Declare Function NSFDbOpen_WIN Lib LIBNAME_WIN Alias "NSFDbOpen" ( _
Byval PathName As String, rethDB As Integer ) As Integer

Declare Function NSFDbOpen_SOL Lib LIBNAME_SOL Alias "NSFDbOpen" ( _
Byval PathName As String, rethDB As Integer ) As Integer

Declare Function NSFDbOpen_AIX Lib LIBNAME_AIX Alias "NSFDbOpen" ( _
Byval PathName As String, rethDB As Integer ) As Integer

Declare Function NSFDbOpen_OS400 Lib LIBNAME_OS400 Alias "NSFDbOpen" ( _
Byval PathName As String, rethDB As Integer ) As Integer

Declare Function NSFDbOpen_LINUX Lib LIBNAME_LINUX Alias "NSFDbOpen" ( _
Byval PathName As String, rethDB As Integer ) As Integer



上記はNSFDBOpenの呼び出し例です。プラットフォームごとに異なる名前をAliasで付けています。
勘のいい人であればここまで見れば、だいたいどう処理するか分かるのではないでしょうか?

TransactionLib ではNSFDbOpenの下記のようなラッパー関数を作っています。

Function NSFDbOpen( PathName As String, rethDB As Integer ) As Integer
Select Case PLATFORM
Case WIN32
ret% =NSFDbOpen_WIN( PathName, rethDB )
Case SOLARIS
ret% =NSFDbOpen_SOL( PathName, rethDB )
Case AIX
ret% =NSFDbOpen_AIX( PathName, rethDB )
Case OS400
ret% =NSFDbOpen_OS400( PathName, rethDB )
Case LINUX
ret% =NSFDbOpen_LINUX( PathName, rethDB )
End Select
NSFDbOpen = ret%
End Function


ここでのPLATFORMと言う定数は@Platformの結果を格納しているような変数ですがここは人によってどうにでも実装できるのではないかと思います。(詳細が気になる人はDefaultSettingと言う関数を見てみてください)
「OS毎の処理の違いはラッパー関数で吸収する」と言ってしまえば、何てことない話ですがこういう処理の仕方は参考になりますね。





最新記事