私はVB6で書かれたコンポーネントをVB.NETで書かれた新しいコンポーネントに置き換えたいと思っています。新しいコンポーネントは、これらが置き換えられるまで、他のVB6アプリケーションと連携する必要があります。文字列配列をパラメータとして受け取る関数に問題があります。COMを介してVB6から.NETに初期化されていない配列を渡す方法は?
私は、問題を再現するために、この機能が含まれているVB6のクラスを使用しています:
Public Function MyMethod(arr() As String, arr2() As String, Result$) As Integer
Result = Join(arr, ", ")
MyMethod = 0
End Function
私は成功した「こんにちは、World」を表示する、次のようにテストプログラム(VB6)からそれを呼び出すことができます。
Dim obj As Object
Dim arr() As String
Dim arr2() As String
Dim result As String
Set obj = CreateObject("MyHelloWorld.MyClass")
'Set obj = CreateObject("HelloWorldCOMNet.MyNetClass")
arr = Split("Hello World", " ")
'ReDim arr2(0)
result = ""
If Not obj.MyMethod(arr, arr2, result) Then
MsgBox result
End If
実際のVB6アプリケーションを変更することはできませんが、VB6 ActiveXコンポーネントを.NETで記述されたクラスに置き換えます。新しいクラスは次のようになります。
<ComClass("cd74ab4a-76ca-4c84-9f49-147e6f6ac01f", "b3314f71-cb8d-48ea-bfe6-9d1995aa4f58", "40c30052-0cc8-4ef6-b1e8-92e4ddbcb515")> _
Public Class MyNetClass
Public Sub New()
MyBase.New()
End Sub
Public Function MyMethod(ByRef arr() As String, ByRef arr2() As String, ByRef result As String) As Short
result = String.Join(", ", arr) + " from .NET"
Return 0
End Function
End Class
私はテストアプリケーションにSet obj = CreateObject("HelloWorldCOMNet.MyNetClass")
でSet obj = CreateObject("MyHelloWorld.MyClass")
を置き換えることによってそれをテストします。
.NETクラスのコンストラクタでブレークポイントを使用して、実行されたことを確認しました。
テストアプリケーションがMyMethod
を呼び出すと、FatalExecutionEngineException
が発生します。
エラーを第2パラメータarr2
に絞り込んだ。 ReDim arr2(0)
を使用して変数を初期化すると、.NETコードが機能します。だから私の推測は、この変数は初期化されていないという事実に関連しているということです。残念ながら、私は実際のVB6アプリケーションを変更することはできません。
私はOleWooを使ってメソッドのシグネチャを比較し、それらは同じであるように見えます(idを除く)。
.NET関数のシグネチャを変更して、初期化されていない文字列配列を受け入れる方法を教えてください。
編集:OleWooからの出力:
[id(0x00000001)]
short MyMethod(
[in, out] SAFEARRAY(BSTR)* arr,
[in, out] SAFEARRAY(BSTR)* arr2,
[in, out] BSTR* result
);
https://stackoverflow.com/q/35190653/11683とhttps://stackoverflow.com/q/39351476/11683に基づいて、私はそれを 'Array'と宣言し、マーシャリング属性を適用しようとします。 – GSerg
私はこれに似た解決策を望んでいます。残念ながら、私はそれを働かせることはできません。 'ByRef arr2 As Array'では、「無効なプロシージャコールまたは引数(エラー5)」および「 ByRef arr2 As Array'と同じ例外が発生します。私は最後のものが働くことを期待した。 ByRefやByValも違いはありません。私はOleWooからの出力で質問を更新しました。 –
BenZinra
解決策を探している間、必要に応じて配列を受け取る予想されるシグネチャでVB6でDLLを作成し、.NETで実際の実装を呼び出します。しかし、私は、マーシャルが空の配列をマーシャリングできないことに驚いています - 少なくとも「Nothing」。 – GSerg