IUnknown
シンクへのを受け入れるレガシー COM コントロール (コア) があります。目的は、コアがこのシンク インターフェイスを介してデータを読み書きできるようにすることです。コア/シンク ポインターは現在、レガシー システムで使用されており、簡単に変更することはできません。
私が抱えている問題は、マネージ コードから Core を呼び出して、マネージ コードにシンクを実装しようとする (試行する) オブジェクトを渡そうとしたときです。シンクを呼び出す準備ができているところまで Core をデバッグしました。通話の前 (後ではありません) に、次のようなメッセージが表示されます。
実行時チェックの失敗 #0 - ESP の値が関数呼び出しで適切に保存されませんでした...
私は純粋なレガシ コードでこれらを確認し、実行してきましたが、マネージ コードの導入には当惑しました。
以下は、私が必要だと考える 2 つのインターフェースの最小の表現です。
interface ICore : IDispatch
{
[id(1), helpstring("method Init")] HRESULT Init([in] IUnknown *pDataManSink);
HRESULT FireOnImport([in] LPCOLESTR pszFormName, [in] LPCOLESTR pszTagName, [in] VARIANT pszData);
... more methods
}
IDL からのデータ アクセスの「シンク」 (問題のデモンストレーションを容易にするために縮小)
interface IDataManagerSinkEx : IUnknown
{
[helpstring("method ReadData")] HRESULT ReadData([in] LPCTSTR pszDataKey, [out, retval] BSTR* pbsData);
[helpstring("method WriteData")] HRESULT WriteData([in] LPCTSTR pszDataKey, [in] LPCTSTR pszData);
[helpstring("method ReadDataEx")] HRESULT ReadTagEx([in] LPCTSTR pszDataKey, [out] short *pwExtraInfoOut, [out, retval] BSTR *pbsData);
[helpstring("method WriteDataEx")] HRESULT WriteTagEx([in] LPCTSTR pszDataKey, [in] short wExtraInfo, [in] LPCTSTR pszData);
}
C# でシンクのさまざまな実装を試してみましたが、役に立たなかったり、エラー状態が変化したりしませんでした。これが最新の実装です。はい、タイプ lib のインターフェイス定義を使用しても機能しなかったため、インターフェイス定義を手作業でコーディングしました。(同問題)
[ComImport]
[Guid( "AB79770E-8143-45E6-B082-E985E6DFA5CB" )]
[InterfaceType( ComInterfaceType.InterfaceIsIUnknown )]
public interface IMyDataManagerSinkEx
{
[PreserveSig]
int ReadData( [MarshalAs( UnmanagedType.LPStr )]string pszDataKey, out string data );
[PreserveSig]
int WriteTag( [MarshalAs( UnmanagedType.LPStr )]string pszDataKey, [MarshalAs( UnmanagedType.LPStr )]string pszData );
[PreserveSig]
int ReadTagEx( [MarshalAs( UnmanagedType.LPStr )]string pszDataKey, out short pwExraInfoOut, out string dataOut );
[PreserveSig]
int WriteTagEx( [MarshalAs( UnmanagedType.LPStr )]string pszDataKey, short wExtraInfo, [MarshalAs( UnmanagedType.LPStr )]string pszData );
}
class public SinkImpl : IMyDataManagerSinkEx
{
[PreserveSig]
public int ReadData( [MarshalAs( UnmanagedType.LPStr )]string pszDataKey, out string data )
{
throw new NotImplementedException();
}
[PreserveSig]
public int WriteTag( [MarshalAs( UnmanagedType.LPStr )]string pszDataKey, [MarshalAs( UnmanagedType.LPStr )]string pszData )
{
throw new NotImplementedException();
}
[PreserveSig]
public int ReadTagEx( [MarshalAs( UnmanagedType.LPStr )]string pszDataKey, out short pwExraInfoOut, out string dataOut )
{
throw new NotImplementedException();
}
[PreserveSig]
public int WriteTagEx( [MarshalAs( UnmanagedType.LPStr )]string pszDataKey, short wExtraInfo, [MarshalAs( UnmanagedType.LPStr )]string pszData )
{
throw new NotImplementedException();
}
}