2009-11-25 27 views
0

我有一個遺留的COM控件(核心),它接受一個接收器IUnknown。目的是允許Core通過該接收器接口讀取/寫入數據。 Core/Sink指針目前在遺留系統中使用,不易修改。在託管(C#)代碼中實現COM「接收器」

我遇到的問題是當我嘗試從託管代碼調用Core並傳入一個對象(嘗試)在託管代碼中實現接收器時。我已經調試了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#水槽的實現的,沒有效果或更改錯誤條件。這是最新的實現,是的,我手動編寫了接口定義,因爲使用類型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(); 
    } 
} 
+0

也許感興趣:http://stackoverflow.com/questions/1787422/an-idiomatic-way-of-wrapping-a-possibly-transient-object – 2009-11-25 16:48:56

+0

你的本地COM服務器是用MBCS還是Unicode編譯的? – 2009-11-25 17:09:30

+0

@本,感謝您的鏈接,但是,這似乎並沒有幫助。 @ Sheng Jiang,COM服務器是用MBCS構建的。我可以修改它並建立源代碼;但是,由於其他限制,它必須保持MBCS並且不能移動到Unicode。 – DevSolo 2009-11-30 20:48:09

回答

1

ESP問題通常意味着你在DLL的運行時庫之間有某種混淆。例如,在我們的代碼庫中,有很多COM對象,如果這些對象中的某些對象的當前COM註冊來自調試版本,而其他註冊屬於版本版本,那麼當調用方法時您將得到ESP錯誤這些對象提供的接口。

我有一個腳本,它註冊了我們代碼庫中所有已知的COM對象。