LOTUSSCRIPT 言語


配列、型、オブジェクトを引き渡す
OS/2 では、C 関数への配列、型、およびオブジェクトの引数の引き渡しはサポートされていません。

配列を引数として引き渡す

LotusScript では、配列はプライベートな形式で格納されるので、C 関数が LotusScript 用に特別に作成されていなければ、C 関数に配列を参照渡しできません。以下の例では LotusScript から long 型の配列を参照する C 関数の宣言と実行の方法を示しています。

LotusScript:

Declare Function LSArrayArg Lib "MYDLL" (ArrLng () As Long)_
As Long
Dim MyArr(0 to 5) As Long
Print LSArrayArg(MyArr)

C 関数:

long C_CALL_TYPE LSArrayArg(LSsValueArray *pLSArr)
{
    long *pData=pLSArr->Data;
     //pData points to first array element
    return pData[0]+pData[1]; //Sum first 2 array elements
}

または、

long C_CALL_TYPE LSArrayArg(long **pLSArr)
{
    long *pData=*pLSArr;
    //pData points to first array element
    return pData[0]+pData[1]; //Sum first 2 array elements

C_CALL_TYPE は、呼び出し規則 (Pascal、STDCALL、_System、CDEL) です。

他の C 関数では Windows 関数 SetBitmapBits のような配列が必要な場合もあります。次の例のようにキーワード Any の参照を使用して、配列の先頭の値を引き渡すこともできます。

LotusScript:

Declare Function FncArrayArg(A As Any) As Long
Dim MyArr(0 to 5) As Long
Print FncArrayArg(MyArr(0))

C 関数:

long C_CALL_TYPE FncArrayArg(long *pArr)
{
    return pArr[0]+pArr[1]; //Sum first 2 array elements
}

型を引数として引き渡す

C 関数の中には、パラメータとしてのデータ構造体を必要とするものがあります。たとえば、Windows API 関数の GetBrushOrgEx は、構造体を示すポインタを必要とします。Point など、適切なデータ型を定義し、その型定義を使用して C 関数を宣言できます。型変数は参照渡しされるので、C 関数はその型の変数を記憶している領域への 4 バイトのポインタを受け取ります。

LotusScript では、C 関数の Declare ステートメントの型パラメータで、省略可能な string 型、Unicode または LMBCS を指定できます。型の引数を 1 つとる関数 UniTest、および型の引数を 1 つとる関数 LMBCSTest の場合、宣言は次の形式になります。この場合、t1 はユーザー定義のデータ型です。

Declare Function UniTest Lib "Unilib" (typArg As Unicode t1)_
As Long
Declare Function LMBCSTest Lib "lmbcslib" _
(typArg As LMBCS t1) As Long

最初の例で、t1 型とそこにネストされた型のすべての文字列 (固定長と可変長) は、Unicode 文字列として渡されます。第 2 の例で、t1 型とそこにネストされた型のすべての文字列 (固定長と可変長) は、LMBCS 文字列として渡されます。

この方法で Unicode または LMBCS を指定しなければ、デフォルトでは、型の引数内のすべての文字列がプラットフォーム固有の文字セットで渡されます。これは LotusScript リリース 2 との互換性があります。

Variant 型の変数に含まれる文字列には、影響はありません。この変更には LotusScript リリース 2 との互換性がないので注意してください。これは、プラットフォームに対する変換が、既定で文字列を含む型に呼び出されるからです (以前は、これらの文字列はプラットフォーム固有の文字セット文字列として渡されていました)。

型に固定長の Unicode でない文字列が入っている場合は、構造体全体をコピーして、そのサイズを調整しなければなりません。構造体のサイズは小さくなります (文字列の長さは固定で、保持しなければならないため、各固定長文字列のバイト数はプラットフォームまたは LMBCS に変換すると半分になります)。これは、長さが 20 の Unicode 文字列をプラットフォーム (DBCS) 内で表すには 20 バイト超が必要なので、文字列が切り捨てられる (情報が失われる) 可能性があることを暗示しています。可変長文字列はポインタとして表されるので、情報は失われません。

LotusScript は、型のメンバをその本来の境界に合わせて、プラットフォーム間で変換できるようにします。
データ型境界合わせ
Boolean 型2 バイト
Byte 型1 バイト
Integer 型2 バイト
Long 型4 バイト
Single 型4 バイト
Double 型8 バイト
Currency 型4 バイト
String 型 (LMBCS)2 バイト
String 型 (Unicode)2 バイト
String 型 (プラットフォーム)1 バイト
Variant 型8 バイト

境界合わせの結果は、Windows 3.1 や Windows 95 のプラットフォーム固有の境界とは一致しなくなります。たとえば、LotusScript では型のメンバ B が 4 バイト境界上に合わせられますが、Windows 3.1 では 2 バイトの境界上になります。

Type telMet
  A As Integer
  B As Long
End Type

オブジェクトを引数として引き渡す

オブジェクトを C 関数に渡すと、C 関数はオブジェクト内で取り出されたデータへの 4 バイトのポインタを受け取ります。データには文字列、配列、リスト、製品固有のオブジェクトへのポインタが含まれることがあるので、C 関数がオブジェクトの内部構造体を完全に認識しないことがあります。C 関数は、最も単純なオブジェクトを操作するときにだけ使用するようにしてください。

例 1

' The following statements declare the C function
' SetBitmapBits.Its 3rd argument is an array argument.This is
' declared as type Any.In the function call, passing
' bitArray(0) passes the array by reference.
Declare Sub SetBitmapBits Lib "_privDispSys" _
  (ByVal hBM As Integer, ByVal cBytes As Long, pBits As Any)
' ...
SetBitmapBits(hBitmap, cBytesInArray, bitArray(0))

例 2

type mytype
mName as string
end type

class myclass
mName as string
end class

function VariantParam( v as Variant) as string
dim tempstr as string
tempstr = TypeName(v)
VariantParam = tempstr
end function

sub initialize
dim myinteger as integer
dim mylong as long
dim mystring as string
dim myintlist list as integer
dim myintarray() as integer
dim mymytype as mytype
dim mymyclass as myclass

messagebox variantparam(myintlist)

messagebox variantparam(myintarray)

'Error:T009 データ型が一致しません:MYMYTYPE
'messagebox variantparam(mymytype)

messagebox variantparam(mymytype)

end sub

関連項目