簡體   English   中英

COM互操作和指向C#中的接口的指針的封送處理

[英]COM interop and marshaling of a pointer to a pointer to an interface in C#

我正在嘗試在C#應用程序中使用Microsoft的Text Services Framework。 到目前為止,一切都進行得很順利,但是我遇到了讓我感到困惑的事情。 根據MSDN文檔,ITfFnReconversion接口發布了此方法:

    HRESULT GetReconversion(
  [in]   ITfRange *pRange,
  [out]  ITfCandidateList **ppCandList
);

我在C#中聲明為:

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetReconversion([In, MarshalAs(UnmanagedType.Interface)] ITfRange pRange, [Out, MarshalAs(UnmanagedType.Interface)] out ITfCandidateList ppCandList);

像這樣打電話:

ITfCandidateList candidateList;    
reconversionInstance.GetReconversion(range, out candidateList);

reconversionInstance和range的值是較早設置的,我相信它們是有效的。 每次執行此行時,我都會收到一個訪問沖突錯誤,表明有人嘗試讀取或寫入受保護的內存。 我假設這是由於對候選人列表參數進行了不正確的封送處理,但是還有其他可能性。

鑒於已將參數聲明為指向指針的指針,我還嘗試將其作為IntPtr傳遞,如下所示:

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetReconversion([In, MarshalAs(UnmanagedType.Interface)] ITfRange pRange, [Out, MarshalAs(UnmanagedType.SysInt)] out IntPtr ppCandList);

    IntPtr candidateList;    
    reconversionInstance.GetReconversion(range, out candidateList);

但是卻留下了同樣的錯誤。

我如何正確地將其編組,以便獲得ITfCandidateList的實例?

為了澄清起見,這是我導入它們時的接口,盡管如上所述,我為GetReconversion嘗試了一些不同的簽名:

    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("4CEA93C0-0A58-11D3-8DF0-00105A2799B5")]
    public interface ITfFnReconversion : ITfFunction
    {
                [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void GetDisplayName([Out, MarshalAs(UnmanagedType.BStr)] out string pbstrName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void QueryRange([In, MarshalAs(UnmanagedType.Interface)] ITfRange pRange, [In, Out, MarshalAs(UnmanagedType.Interface)] ref ITfRange ppNewRange, [Out, MarshalAs(UnmanagedType.Bool)] out bool pfConvertable);
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void GetReconversion([In, MarshalAs(UnmanagedType.Interface)] ref ITfRange pRange, [Out, MarshalAs(UnmanagedType.SysInt)] out IntPtr ppCandList);
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void Reconvert([In, MarshalAs(UnmanagedType.Interface)] ITfRange pRange);
    }
[ComImport, Guid("A3AD50FB-9BDB-49E3-A843-6C76520FBF5D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITfCandidateList
{
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
    void EnumCandidates([Out, MarshalAs(UnmanagedType.Interface)] out IEnumTfCandidates ppEnum);
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
    void GetCandidate([In] uint nIndex, [Out, MarshalAs(UnmanagedType.Interface)] out ITfCandidateString ppCand);
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
    void GetCandidateNum([Out] out uint pnCnt);
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
    void SetResult([In] uint nIndex, [In, ComAliasName("TSF.TfCandidateResult")] TfCandidateResult imcr);
}

這里顯然有問題。 ITfCandidateList **ppCandList無法轉換為簡單輸出:這是指向ITfCandidateList指針的指針。

我認為,您需要將其定義為IntPtr ,然后嘗試使用Marshal.PtrToStructure.讀取內存的該部分Marshal.PtrToStructure.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM