我有一个接受接收IUnknown
器的旧 COM 控件(核心)。目的是让 Core 通过这个 sink 接口读/写数据。Core/Sink 指针目前在遗留系统中使用,不容易修改。
我遇到的问题是,当我尝试从托管代码调用 Core 并传入一个(尝试)在托管代码中实现接收器的对象时。我已经将核心调试到它准备调用接收器的程度。在通话之前(而不是之后),我收到类似于以下内容的消息:
运行时检查失败 #0 - ESP 的值未在函数调用中正确保存...
我已经在纯遗留代码中看到并解决了这些问题,但是托管代码的引入让我感到困惑。
这是我认为必要的两个接口的最小表示。
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# 中尝试了各种接收器的实现,但无济于事或错误条件发生变化。这是最新的实现,是的,我手动编码了接口定义,因为使用类型库中的那个不起作用。(同样的问题)
[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();
}
}