DOBON.NET DOBON.NETプログラミング掲示板過去ログ

VB.net⇔DDL間の構造体配列の値の受け渡し

環境/言語:[使用言語(VB.NET, Pro-C)]
分類:[.NET]

DDLと構造体配列の値の受け渡しができなくて一週間悩み続けて困ってます。
VB6からのコンバート作業を行っているのですか、VB6ではDeclare区で
As Anyを使って構造体配列にDLL側からデータを受けていたのですが
ご教授お願いします。

<VB.net>
Public Structure DAT
 <VBFixedString(10), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=10)> Public ch() As String
 Public Sub Initialize()
  ReDim ch(9)
 End Sub
End Structure
Public Declare Function GetData Lib "AAA.dll" ( _
ByRef Dat As DAT _
) As Integer

Dim Dat As DAT
Dat.Initialize()
ret = GetData(Dat)
For i = 0 To 9
 Msgbox(Dat.ch(i))
Next

<C>
typedef struct{
 char chr[10];
} DAT;
extern int WINAPI GetData(char *buf ) {
 DAT *ptr = (DAT*)buf
 for (i=0;i<10;i++) {
  memcpy(ptr + i, 編集データ, sizeof(DAT));
 }
}
■No2291に返信(に〜くんさんの記事)
> DDLと構造体配列の値の受け渡しができなくて一週間悩み続けて困ってます。

DDLじゃなくてDLLですよね?(タイトルも)

> <VB.net>
> Public Structure DAT
>  <VBFixedString(10), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=10)> Public ch() As String
>  Public Sub Initialize()
>   ReDim ch(9)
>  End Sub
> End Structure

C言語側の定義のchar*(charの[10])はVB.NETで言えば、StringまたはByte()になります。

Public Structure DAT
Public ch() As Byte
 Public Sub Initialize()
  ReDim ch(9)
 End Sub
End Structure

としてはどうでしょうか?

受け取ったデータを文字列として扱う必要があるなら、
適切なSystem.Text.Encodingクラスを取得し、
そのGetStringメソッドでバイト配列から文字列に変換できます。
ご教授ありがとうございます。

> DDLじゃなくてDLLですよね?(タイトルも)
お恥ずかしい...

>
> Public Structure DAT
> Public ch() As Byte
>  Public Sub Initialize()
>   ReDim ch(9)
>  End Sub
> End Structure
>
> としてはどうでしょうか?
>
> 受け取ったデータを文字列として扱う必要があるなら、
> 適切なSystem.Text.Encodingクラスを取得し、
> そのGetStringメソッドでバイト配列から文字列に変換できます。

下の様にやってはみてもダメでした。やはり配列データの受けはできないのかな?

Public Structure DAT
<VBFixedArray(10), MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)>
Public ch() As Byte
 Public Sub Initialize()
  ReDim ch(9)
 End Sub
End Structure
Public Declare Function GetData Lib "AAA.dll" ( _
ByRef Dat() As DAT _
) As Integer

Dim Dat(100) As DAT
Dim SdateStr As String

For i = 0 To 99
Dat(i).Initialize()
Next

ret = GetData(Dat())

For i = 0 To 99
SdateStr = Trim(System.Text.Encoding.ASCII.GetString(Dat(i).ch))
  Msgbox(SdateStr)
Next
> 下の様にやってはみてもダメでした。やはり配列データの受けはできないのかな?

どういうデータを期待して、どのような結果になったのでしょう?
また、その場合、DLLからは実際にはどんなデータが出力されているのですか?

> Public Structure DAT
> <VBFixedArray(10), MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)

UnmanagedType.ByValArrayではなくUnmanagedType.LPArrayじゃないですか?

> Public ch() As Byte
>  Public Sub Initialize()
>   ReDim ch(9)
>  End Sub
> End Structure

> Public Declare Function GetData Lib "AAA.dll" ( _
> ByRef Dat() As DAT _
> ) As Integer

最初に提示してあったGetData関数と仕様が変わってるんですけど・・・

C言語のDLLからは何を返したいのですか?
Shift JIS(またはASCIIコードだけ)の文字列を返したいのでしょうか?

であれば、構造体も必要なく、

Public Ansi Declare Function GetData Lib "AAA.dll" _
( _
ByVal Dat As System.Text.StringBuilder _
) As Integer

のように宣言し、

Dim sb As New StringBuilder(10)
ret = GetData(sb)
Debug.WriteLine(sb.ToString())

のように使用すればよいと思います。
すいません。私の説明不足ですね。

ようは以下のVB6で動いていたものをVB.netでも実現したいだけなんですけど...
DLL(Getdata)からは構造体(ST_A10件分)のデータが入ってきます。

<VB6>
Type ST_A
ST_A_1(40) As Byte
ST_A_3 As Long
End Type

Declare Function Getdata Lib "AAA.dll" ( _
ByRef st As Any _
) As Long

Dim st(9) As ST_A

GetData(st(0))
For i = 0 To 9
'構造体配列分の処理
Next
<StructLayout(LayoutKind.Sequential)> _
Public Structure ST_A
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=41)> _
ST_A_1() As Byte
ST_A_3 As Integer
End Structure

Declare Function Getdata Lib "AAA.dll" ( _
ByRef st() As ST_A _
) As Integer

Dim st(9) As ST_A

GetData(st)
For i = 0 To 9
'構造体配列分の処理
Next

DOBON.NET | プログラミング道 | プログラミング掲示板