- PR -

VC++作成のAPIとVB.Net間でユーザ定義型の値を配列で受け渡しするには?

1
投稿者投稿内容
ほげほげ
会議室デビュー日: 2005/07/26
投稿数: 1
投稿日時: 2005-07-26 14:45
開発環境
OS:Windows2000 Pro SP4
VBバージョン:MicroSoft VisualBasic.Net 2003 Ver1.1 SP1

VS6のVC++で作成された既存のAPIとVB.Net間でユーザ定義型の値を配列で
受け渡しをしようとしています。
既存のAPI側は修正しないでVB.Net側でなんとかしたいと考えています。

VB.Netでコーディングしデバック実行でAPIへユーザ定義型の配列を渡そうとすると

「System.Runtime.InteropServices.SafeArrayTypeMismatchException' の
     ハンドルされていない例外が Project1.exe で発生しました。
 追加情報 : 指定された配列は期待されたタイプではありません。」

のエラーメッセージが表示されます。

次にAPIからユーザ定義型の値を配列を受け取ろうとデバック実行すると

「System.NullReferenceException' のハンドルされていない例外が
     Project1.exe で発生しました。
 追加情報 : オブジェクト参照がオブジェクト インスタンスに設定されていません。」

のエラーメッセージが表示されます。

おそらくAPI定義のSafeArrayでマーシャライズがどうも
間違っている気がします。

シンプルな数値型の配列の受け渡しは色々調べながらも実現はしましたが
ユーザ定義の配列の受け渡しが出来ません。
どうかどなたかご教授願います。



VB.Netでユーザ定義の構造体とAPIは下記のようにしました。
' ***************** VB.Netソース *****************
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Public Structure mcTestValElem
<MarshalAs(UnmanagedType.LPTStr)> Public name As String
<MarshalAs(UnmanagedType.U4)> Public index As Integer
<MarshalAs(UnmanagedType.LPTStr)> Public value As String
End Structure

Declare Auto Function TestSet Lib "TESTAPI" Alias "_TestSet@4" ( _
<MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VT_USERDEFINED)> ByRef setList() As mcTestValElem _
) As Integer

Declare Auto Function TestGet Lib "TESTAPI" Alias "_TestGet@4" ( _
<MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VT_USERDEFINED)> ByVal getList() As mcTestValElem _
) As Integer


VS6のVC++のロジック(テスト用に省略してあります)は下記のようになっています。
// VS6 VC++ソース

struct mcVBTestValElem {
BSTR name;
long index;
BSTR value;
};

extern "C" __declspec( dllexport ) long PASCAL TestSet( LPSAFEARRAY FAR *in_dat )
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
long LBound, UBound;

SafeArrayGetLBound(*in_dat, 1, &LBound);
SafeArrayGetUBound(*in_dat, 1, &UBound);
return 1;
}

extern "C" __declspec( dllexport ) long PASCAL TestGet( LPSAFEARRAY FAR *results )
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

LPSAFEARRAY out_dat;
long pos;
mcVBTestValElem     elem;
CString name;
CString value;
long index;

setlocale( LC_ALL, "" );

if (SafeArrayAllocDescriptor(1, &out_dat) != S_OK) {
return 0;
}

out_dat->cbElements = sizeof(mcVBTestValElem);
out_dat->fFeatures = 0;
out_dat->rgsabound[0].cElements = 3;
out_dat->rgsabound[0].lLbound = 0;
if (SafeArrayAllocData(out_dat) != S_OK) {
return 0;
}

for (pos = 0; pos < 3; pos++) {
name.Format("get-name-漢字-%d", (111 * (pos + 4)));
index = (111 * (pos + 4));
value.Format("get-value-半角カタカナ-%d", (111 * (pos + 4)));
elem.name = name.AllocSysString();
elem.index = index;
elem.value = value.AllocSysString();
SafeArrayPutElement(out_dat, &pos, &elem);
// TRACE
TraceLog(" +- name(%s) index(%d) value(%s)", name, index, value);
}

if (*results != NULL) {
SafeArrayDestroyData(*results);
SafeArrayDestroyDescriptor(*results);
}
*results = out_dat;
return 1;
}
1

スキルアップ/キャリアアップ(JOB@IT)