实施COM;“水槽”;在托管(C#)代码中
我有一个旧的COM控件(核心),它接受一个实施COM;“水槽”;在托管(C#)代码中,c#,iunknown,C#,Iunknown,我有一个旧的COM控件(核心),它接受一个IUnknown到接收器。其目的是允许内核通过该接收器接口读/写数据。核心/接收器指针目前在遗留系统中使用,不易修改 我遇到的问题是,当我试图从托管代码调用核心并传入一个(试图)在托管代码中实现接收器的对象时。我已经调试了内核,它正准备调用接收器。在通话之前(而不是之后),我收到一条类似于以下内容的信息: 运行时检查失败#0-未在函数调用中正确保存ESP的值 我已经在纯遗留代码中看到并解决了这些问题,但托管代码的引入让我感到困惑 以下是我认为必要的两个接
IUnknown
到接收器。其目的是允许内核通过该接收器接口读/写数据。核心/接收器指针目前在遗留系统中使用,不易修改
我遇到的问题是,当我试图从托管代码调用核心并传入一个(试图)在托管代码中实现接收器的对象时。我已经调试了内核,它正准备调用接收器。在通话之前(而不是之后),我收到一条类似于以下内容的信息:
运行时检查失败#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开始的数据访问“接收器”(为方便问题演示而减少)
我在C#中尝试了多种接收器实现,但都没有效果,也没有改变错误条件。这是最新的实现,是的,我手工编写了接口定义,因为使用类型库中的接口定义不起作用。(同一期)
ESP问题通常意味着DLL的运行库之间存在某种混淆。例如,在我们的代码库中有许多COM对象,如果其中一些对象的当前COM注册来自调试版本,而其他对象的注册来自发布版本,那么在这些对象提供的接口上调用方法时,您将收到ESP错误
我有一个脚本,可以注册我们代码库中所有已知的COM对象。可能有兴趣:您的本机COM服务器是用MBCS还是Unicode构建的?@Ben,谢谢您的链接,但是,这似乎没有帮助@盛江,COM服务器是用MBCS构建的。我可以对其进行更改并构建源代码;但是,由于其他限制,它必须保持MBCS,并且不能移动到Unicode。
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);
}
[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();
}
}