|
■No75372 (魔界の仮面弁士) に追記 > iRet = Test1(oType) > おぉ、エラーなく呼べた!! > 呼び出しまではできるようになったので、次は、DLL からの情報を受け取れるかどうかの確認だな。
今のところ、iRet の値は &H0024。これは DLL 側の実装を LPSAFEARRAY psa = *Type1; VARTYPE vt; SafeArrayGetVartype(psa, &vt); return vt; にしているからなので、内容的には正しそう。(&H0024 は 定数 VT_RECORD と同じ値)
でも、DLL 側で値を編集するのってどうやるんだろう。 C++ は全然知らない上に、SAFEARRAY の API にも詳しくないんだよなぁ。
とりあえず、見様見真似で書いてみよう。
LPSAFEARRAY psa = *Type1; long lb, ub; SafeArrayLock(psa); SafeArrayGetLBound(psa, 1, &lb); // lb = LBound(Type1, 1) SafeArrayGetUBound(psa, 1, &ub); // ub = UBound(Type1, 2) SafeArrayUnlock(psa); Structure1 *p = NULL; SafeArrayAccessData(psa, (void**)&p); for(long idx = lb; idx <= ub; idx++) { p[idx].Long1 += 70; p[idx].Long2 += 80; p[idx].Long3 += 90; } SafeArrayUnaccessData(psa); return ub - lb + 1; // 要素数
C++ は苦手というか勉強したことが無い(C が少し読める程度)ので、 これで正しいのかどうかは全然自信が無いけど、一応コンパイルは通ったようだ。
エラーチェックの処理とか入れてないのが不安だけど、 とりあえず VB6 から呼んでみよう。
For n = 0 To 9 oType(n).Long1 = n * 100 + 1 oType(n).Long2 = n * 100 + 2 oType(n).Long3 = n * 100 + 3 Next iRet = Test1(oType)
よしよし、oType(2) が { 201, 202, 203 } → { 271, 282, 293 } に書き換わっているな。
次は、VB.NET で呼んでみると…こっちも大丈夫そうだ!
ってことで完成形のお披露目ー★
Imports System.Runtime.InteropServices Public Module Module1 <ComVisible(True), Guid("8D60602D-452A-48A1-ACEF-AF148A6E41B8")> _ Public Structure Structure1 Dim Long1 As Integer Dim Long2 As Integer Dim Long3 As Integer End Structure
Declare Function Test1 Lib "TestFunc.dll" _ (<MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VarEnum.VT_RECORD)> ByRef oStructure() As Structure1) As Integer
Public oType(9) As Structure1 Sub Main() Dim iRet As Integer = -1 For n = 0 To 9 oType(n).Long1 = n * 100 + 1 oType(n).Long2 = n * 100 + 2 oType(n).Long3 = n * 100 + 3 Next iRet = Test1(oType) End Sub
End Module
|