2012-07-27 26 views
4

我有一個非託管的C++應用程序作爲COM客戶端和C#COM服務器。 現在我想COM服務器可以調用一個C++函數。將C++函數指針設置爲C#委託

C#:

[ClassInterface(ClassInterfaceType.AutoDual)] 
public class SomeType 
{ 
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
    public delegate void DeleCallBack(string info); 
    public DeleCallBack CallBack; 
    public void SetCallBack(ref IntPtr ptr) 
    { 
     CallBack = (DeleCallBack)Marshal.GetDelegateForFunctionPointer(ptr, typeof(DeleCallBack)); 
    } 
} 

C++:

HRESULT hr = E_FAIL; 
CComPtr<WindowsFormsApplicationVC9::_SomeType> spTmp; 
hr = spTmp.CoCreateInstance(__uuidof(WindowsFormsApplicationVC9::SomeType)); 
if (SUCCEEDED(hr)) 
{ 
    spTmp->SetCallBack(OnCallBack); 
} 
void OnCallBack(BSTR info) 
{ 
    // c++ function call...; 
} 

我不知道它是對OnCallBack函數指針只傳遞給SetCallBack的正確途徑。 我注意到調用GetDelegateForFunctionPointer的一些示例應該GetProcessAddress來獲取函數指針地址,但我不能這樣做,因爲可能有不同的C++ COM客戶端具有不同的函數名稱。

有什麼建議嗎?

+0

在整個過程的邊界上傳遞指針看起來很奇怪,你已經提到了它。也許你應該將C++回調包裝在COM接口中,並將ICallbackInterface指針傳遞給C#?仍然會有數據傳遞的問題。一個小問題 - 在你的C#回調委託聲明中,你應該爲字符串使用[MarshalAs(UnmanagedType.BStr)]屬性。 – 2012-07-27 08:09:28

回答

0

一種方法是通過__declspec(dllexport)公開您的C++函數,然後爲這些函數編寫P/Invoke。現在你可以使用這些P/Invoke函數作爲代表。

深入研究這本質上是GetProcAddress方法,但C#編譯器使它在語法上更適合您。

+0

以我的理解,使用dll導出是C#可以從C++調用回調的唯一方法。 :( – ArdenZhao 2012-07-28 03:35:25