VB.net VC++.net の構造体配列について

解決


JMM  2005-08-05 15:34:16  No: 91280

はじめまして。
早速ですが、VB.net、VC++.net間のDLLでの
構造体配列の引渡しで行き詰まっています。
過去ログも読み、参考にさせていただきましたが、うまく動きません。
単純な構造体の場合は正常に取得できています。
次のようなコードです。アドバイスをいただけませんでしょうか。
初心者で本当に申し訳ありません。
[VB.net 2003]
Public Structure STRUCTSHEET
  Dim SheetType As String
  Dim SheetName As String
End Structure

Declare Auto Function OnAir Lib "vs.dll" Alias "OnAir" ( _
  <[In](), Out()> ByRef sts() As STRUCTSHEET) As Integer

Private Sub ButtonTest_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonTest.Click
    Dim sts(1) As STRUCTSHEET
    With sts(0)
        .SheetType = "テスト_0"
        .SheetName = "テストデモ_0"
    End With
    With sts(1)
        .SheetType = "テスト_1"
        .SheetName = "テストデモ_1"
    End With
    RetVal = OnAir(sts)
End Sub

[VC++.net 2003]
typedef struct _STRUCTSHEET {
    BSTR SheetType;
    BSTR SheetName;
} STRUCTSHEET[240] ;

EXPORT int __stdcall OnAir(STRUCTSHEET *sts);

EXPORT int __stdcall OnAir(STRUCTSHEET *sts)
{
    MessageBox(NULL, (LPCSTR)sts[0]->SheetType, "メッセージ", MB_OK);
}

よろしくお願いいたします。


K.J.K.  2005-08-05 21:21:02  No: 91281

最大の疑問があるのですが、両者とも.NETであるのならば、
VC++.NETで作ったDLLをVB.NET側で[参照設定]すれば、Declare
などを介せずに使えるようにできません?

んで、それでもDeclareに拘るのならば、MarshalAs属性などで
ガチガチに固めるとか。


あん  2005-08-05 22:31:20  No: 91282

>単純な構造体の場合は正常に取得できています。
成功する構造体はどんなのですか?

Public Structure STRUCTSHEET
    Dim SheetType As String * 50
    Dim SheetName As String * 50
End Structure

とかやればいいのかなあ?


JMM  2005-08-06 02:38:29  No: 91283

> VC++.NETで作ったDLLをVB.NET側で[参照設定]すれば
説明不足で申し訳ありません。
VC.net は使用していますが、C++ のWin32アプリケーションです。
DirectXのライブラリをまとめたものです。
インターフェースとは切り離した状態で動作させる必要があったものですから。

> 成功する構造体はどんなのですか?
Public Structure STRUCTPROGRAMS
    Dim SheetType As String
    Dim SheetName As String
End Structure

Declare Auto Function OnAir Lib "vs.dll" Alias "OnAir" ( _
  <[In](), Out()> ByRef sts As STRUCTSHEET) As Integer

Private Sub ButtonTest_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonTest.Click
    Dim sts As STRUCTSHEET
    With sts
        .SheetType = "テスト_0"
        .SheetName = "テストデモ_0"
    End With
    RetVal = OnAir(sts)
End Sub

のように配列でなければ、VC側では

sts->SheetType

で単純に取得できます。


JMM  2005-08-06 02:54:37  No: 91284

> MarshalAs属性などでガチガチに固めるとか。
どうも、このマーシャリングが理解できていません。
MSDNを何度も読み、設定を変更してテストはしているのですが
うまく動かない状態がほぼ10日も続いています。


JMM  2005-08-06 10:49:38  No: 91285

他にもっと良い手法があるかもしれませんが、
とりあえず、自己解決できました。本当に長い道のりでした。
貴重なアドバイスを頂いた方々には、本当にありがとうございました。

今後、同じような壁にぶつかった方のために
サンプルを書き留めておきます。
結局のところ、C++側でポインタをインクリメントすることで配列を順次移動し、
構造体の要素名から値を取得することができました。
構造体の添字に注目し過ぎた事が遠回りの要因でした。

[VB.net 2003]
Public Structure STRUCTSHEET
  Dim SheetType As String
  Dim SheetName As String
End Structure

Declare Auto Function OnAir Lib "vs.dll" Alias "OnAir" ( _
  <[In](), Out()> ByRef sts() As STRUCTSHEET) As Integer

Private Sub ButtonTest_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonTest.Click
    Dim sts(1) As STRUCTSHEET
    With sts(0)
        .SheetType = "テスト_0"
        .SheetName = "テストデモ_0"
    End With
    With sts(1)
        .SheetType = "テスト_1"
        .SheetName = "テストデモ_1"
    End With
    RetVal = OnAir(sts)
End Sub

[VC++.net 2003]
typedef struct _STRUCTSHEET {
    BSTR SheetType;
    BSTR SheetName;
} STRUCTSHEET ;

EXPORT int __stdcall OnAir(STRUCTSHEET *sts[]);

EXPORT int __stdcall OnAir(STRUCTSHEET *sts[])
{
    MessageBox(NULL, (LPCSTR)sts[0]->SheetType, "メッセージ", MB_OK);
    (*sts)++;
    MessageBox(NULL, (LPCSTR)sts[0]->SheetType, "メッセージ", MB_OK);
}


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加