- PR -

VB.NETからVC++.NET作成DLLの呼出

1
投稿者投稿内容
やぎ
会議室デビュー日: 2003/04/01
投稿数: 14
投稿日時: 2003-04-03 14:05
VB.NETからVC++.NETで作成したDLLを呼び出そうとしていますが、以下の構造体:Person
(構造体の配列を含んでいる構造体)を渡そうとすると、"型 Person のフィールド addr
をマーシャリングできません : この型は構造体フィールドとして、マーシャリングできません。"
というエラーが発生してしまいます。

こういった場合は、どのようにすれば良いのでしょうか?

コード:
Structure Address
    <VBFixedString(40), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=40)> _
                              Public ad As String
End Structure

Structure Person
    <VBFixedString(10), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=10)> _
                              Public Name As String
    <VBFixedArray(4), MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
                              Public addr() As Address
    Public Sub Initialize()
        ReDim addr(4)
    End Sub
End Structure

Declare Function @@@@@ Lib "***.dll" (ByRef p As Person) As Integer


Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-04-03 15:38
こんにちは。

MSDNのこのページを参照してください。←IE以外はIEを騙る設定にしないと見せてもらえないようです。

[StructLayout(LayoutKind::Sequential)] 属性を付け、__gcを宣言し、publicアクセシビリティを指定します。

VC++.NET側
[StructLayout(LayoutKind::Sequential)]
typedef public __gc struct _Person {
// 宣言
} Person;

これでVC.NETのDLLからVB.NETに公開されます。


 VC++.NET側がアンマネージの時は、VB.NET側で宣言します。

<StructLayout(LayoutKind.Sequential)> _
Structure Person
End Structure

[ メッセージ編集済み 編集者: Jitta 編集日時 2003-04-03 16:20 ]
やぎ
会議室デビュー日: 2003/04/01
投稿数: 14
投稿日時: 2003-04-04 08:47
Jittaさん ありがとうございます。

DLLがアンマネージなので、VB.NET側で<StructLayout(LayoutKind.Sequential)>
をつけてみましたが、ダメでした。
入れ子の構造体が配列でない場合は、うまく渡るんですが・・・

DLLの方はVC++6.0からの移行で、特にソースはいじってないんです。
>[StructLayout(LayoutKind::Sequential)] 属性を付け、__gcを宣言し、
>publicアクセシビリティを指定します。
上記を指定しないと無理なのでしょうか?
試しに指定してみましたが、コンパイルエラーとなります。
コンパイルオプションを変更しないといけないのでしょうか?
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-04-04 08:59
こんにちは。
引用:

やぎさんの書き込み (2003-04-04 08:47) より:

入れ子の構造体が配列でない場合は、うまく渡るんですが・・・

DLLの方はVC++6.0からの移行で、特にソースはいじってないんです。
>[StructLayout(LayoutKind::Sequential)] 属性を付け、__gcを宣言し、
>publicアクセシビリティを指定します。
上記を指定しないと無理なのでしょうか?
試しに指定してみましたが、コンパイルエラーとなります。
コンパイルオプションを変更しないといけないのでしょうか?



 こういう場合、「どういうエラーがでました」というのを付けてくださいね。

 配列は、うまくわたりませんね。私も、char配列を渡そうとして、ダメでした。「char配列の場合は、System.Text.StringBuilderを使え」と、MSDNに書いてあります。

 C++の方は、すみません、私マネージC++にしていました。Win32のプロジェクトに__gc宣言はできませんね。で、こういう場合、全然スマートではないのですが、アンマネージC++を使うために、マネージC++のラッパークラスを作りました。マネージC++プロジェクトで、アンマネージな構造体を作り、それでWin32プロジェクトの入出力を担当させます。同じ構造体をマネージ型で作り、コピーして、VB.NETプロジェクトの入出力を行います。

 スマートじゃないし、この方法で正しいのか、他にスマートな方法があるのかわかりませんが、とりあえずそういう作り方をしました。

追記
struct Address の方も、Layout属性を指定しましたか?

[ メッセージ編集済み 編集者: Jitta 編集日時 2003-04-04 09:22 ]
やぎ
会議室デビュー日: 2003/04/01
投稿数: 14
投稿日時: 2003-04-07 10:36
こんにちは。

引用:

こういう場合、「どういうエラーがでました」というのを付けてくださいね。
配列は、うまくわたりませんね。私も、char配列を渡そうとして、ダメでした。「char配列の場合は、System.Text.StringBuilderを使え」と、MSDNに書いてあります。
C++の方は、すみません、私マネージC++にしていました。Win32のプロジェクトに__gc宣言はできませんね。で、こういう場合、全然スマートではないのですが、アンマネージC++を使うために、マネージC++のラッパークラスを作りました。マネージC++プロジェクトで、アンマネージな構造体を作り、それでWin32プロジェクトの入出力を担当させます。同じ構造体をマネージ型で作り、コピーして、VB.NETプロジェクトの入出力を行います。
スマートじゃないし、この方法で正しいのか、他にスマートな方法があるのかわかりませんが、とりあえずそういう作り方をしました。
追記
struct Address の方も、Layout属性を指定しましたか?



申し訳ありません。今後エラー内容も明記するように気をつけます。
やはり、マネージC++のラッパークラスを作る以外、方法はないん
でしょうか・・・
struct Address の方も、Layout属性は指定していました。
他に方法が無いので、とりあえずこの方法でやろうと思います。
ありがとうございました。

1

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