私はC#コードから消耗したい(レガシー)VB6コードを持っています。VB6の文字列配列をC#で使用する
これはthis questionと多少似ていますが、VB6からC#dllを使用する配列を渡すことを指します。私の問題は反対です。
VBでは、あるDLLにはインターフェイスがあり、別のDLLにはインターフェイスがあります。
インタフェース:
[
odl,
uuid(339D3BCB-A11F-4fba-B492-FEBDBC540D6F),
version(1.0),
dual,
nonextensible,
oleautomation,
helpstring("Extended Post Interface.")
]
interface IMyInterface : IDispatch {
[id(...),helpstring("String array of errors.")]
HRESULT GetErrors([out, retval] SAFEARRAY(BSTR)*);
};
cMyImplementationClassで実施(フラグメント):
Private Function IMyInterface_GetErrors() As String()
If mbCacheErrors Then
IMyInterface_GetErrors = msErrors
End If
End Function
私はTlbimp.exeをとC#から機能を呼び出すための試みでこれら2つのDLLを包みました。
public void UseFoo()
{
cMyImplementationClass foo;
...
var result = foo.GetErrors();
...
}
foo.GetErrors()を呼び出すと、SafeArrayRankMismatchExceptionが発生します。私はこれがSafe Arraysセクションhereに記載されているマーシャリングの問題を示していると思います。
tlbimp.exeの/ sysarrayパラメータを使用するか、手動で作成したILを手動で編集することをお勧めします。
原ILは、次のようになります
.method public hidebysig newslot virtual
instance string[]
marshal(safearray bstr)
GetErrors() runtime managed internalcall
{
.override [My.Interfaces]My.Interface.IMyInterface::GetErrors
} // end of method cImplementationClass::GetErrors
更新されたバージョンであるが:
.method public hidebysig newslot virtual
instance class [mscorlib]System.Array
marshal(safearray)
GetErrors() runtime managed internalcall
{
.override [My.Interfaces]My.Interface.IMyInterface::GetErrors
} // end of method cImplementationClass::GetErrors
Iはインタフェースおよび実装の両方に同一の機能署名変更を行いました。このプロセスはhereと記載されています。ただし、関数の戻り値は指定されず( "in"参照が使用されます)、インタフェースも使用されません。コードを実行してC#から呼び出すと、エラーが発生します。
メソッドが見つかりませんでした: 'System.Array MyDll.cImplementationClass.GetErrors()'。
ここからどこに行くのかはわからないが、私が編集したILに何か問題があるようです。
VB6コードを変更せずにC#からこの機能をどのように使用できますか?
--Edit-- "msErrors"の再定義。返されるプライベート配列を初期化します。
ReDim Preserve msErrors(1 To mlErrorCount)
私が正しく理解していれば、その中の「1」は、配列が、私はスロー見る例外の原因である、1ではなく0からインデックスされることを意味しています。
私はあなたはそれが最初に作業していて、ILは、長期的な解決策のように見えるしていません編集を取得したいことを理解しています。 –
多分そうですが、[ここ](https://msdn.microsoft.com/en-us/library/ek1fb3c6(v = vs.100).aspx#cpconeditingmicrosoftintermediatelanguagemsilanchor4)に記載されている変更をマーシャリングすることをお勧めします。 FWIWでは、/ sysarrayフラグは結果として生じるエラーを含む同じネットエフェクトを持つように見えます。 – ayers
VB6コードから返す配列をどのように宣言しているかわかりません。ランク1と下限0を持っていますか?「Dim msErrors(0 To N)As String」のように宣言されていますか?また、mbCacheErrorsがfalseの場合、現在の実装では初期化されていない配列が返されているようです。 – Joe