2012-06-06 36 views
5

Tôi đã quản lý để tạo đối tượng C# COM với các sự kiện. Vui lòng tìm mã bên dưới,Xử lý các sự kiện C# COM trong C++

[Guid("1212674-38748-45434")] 
    public interface ICalculator 
    { 
     int Add(int Num1, int Num2); 
    } 

    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    [Guid("3453674234-84444-84784")] 
    public interface ICalculatorEvents 
    { 
     [DispId(1)] 
     void Completed(int Result); 
    } 

    [ClassInterface(ClassInterfaceType.None)] 
    [ComSourceInterfaces(typeof(ICalculatorEvents))] 
    [Guid("87457845-945u48-4954")] 
    public class Calculator : ICalculator 
    { 
     public delegate void CompletedDelegate(int result); 
     public event CompletedDelegate Completed; 
     public Add(int Num1, int Num2) 
     { 
      int Result = Num1 + Num2; 
      if(Completed != null) 
       Completed(Result); 
     } 
    } 

Tôi đã nhập đối tượng COM này trong ứng dụng bảng điều khiển C++ và có thể gọi phương thức 'Thêm()'. Tôi không chắc chắn làm thế nào để xử lý sự kiện 'Đã hoàn thành' trong ứng dụng C++ của tôi. Bạn có thể vui lòng tư vấn về điều này? Tôi đang tìm cách hiển thị giá trị kết quả trong bảng điều khiển bất cứ khi nào sự kiện này xảy ra.

Vui lòng tìm mã của ứng dụng C++ bên dưới. Sự kiện 'Hoàn thành' không bao giờ được xử lý ở đây. Điều này đi vào một vòng lặp vô hạn.

#import "Calculator.tlb" 
    using namespace Calculator; 
    int Flag = 0; 
    class HandleEvent : public ICalculatorEvent 
    { 
     public: 
      HandleEvent(void); 
      ~HandleEvent(void); 
      HRESULT __stdcall QueryInterface(const IID &, void **); 
      ULONG __stdcall AddRef(void) { return 1; } 
      ULONG __stdcall Release(void) { return 1; } 
      HRESULT __stdcall Completed(int Result); 
    }; 

    HandleEvent::HandleEvent(void) 
    { 
    } 

    HRESULT HandleEvent::Completed(int Result) 
    { 
     printf("Addition Completed, Result: %d", Result); 
     Flag = 1; 
    } 

    HRESULT HandleEvent::QueryInterface(const IID & iid,void ** pp) 
    { 
     if (iid == __uuidof(ICalculatorEvent) || iid == __uuidof(IUnknown)) 
     { 
      *pp = this; 
      AddRef(); 
      return S_OK; 
     } 
     return E_NOINTERFACE; 
    } 

    int _tmain(int argc, _TCHAR* argv[]) 
    { 
     CoInitialize(NULL); 
     Flag = 0; 
     ICalculatorPtr pCalc(__uuidof(Calculator)); 
     pCalc->Add(5, 6); 

     do 
     { 
     }while(Flag == 0); 

     CoUninitialize(); 
     return 0; 
    } 

Xin cảm ơn trước.

+0

Tôi nghĩ rằng bạn đã hoàn thành đối tượng sự kiện sẽ không được gọi vì nó luôn luôn là null. Lớp nào được triển khai giao diện ICalculatorEvents? –

+0

ICalculatorEvents được triển khai trong ứng dụng C++. Vui lòng tìm mã C++ bên dưới, – GeekCandy

+0

Mã C++ ở đâu? –

Trả lời

0

Nếu bạn muốn sử dụng các đại biểu, bạn không cần khai báo giao diện. Thay đổi hàm _tmain() như sau:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CoInitialize(NULL); 
    Flag = 0; 

    EventHandler evh ; 
    ICalculatorPtr pCalc(__uuidof(Calculator)); 
    pCalc->Completed = &evh.Completed() ; 
    pCalc->Add(5, 6); 

    do 
    { 
    }while(Flag == 0); 

    CoUninitialize(); 
    return 0; 
} 

Nếu bạn muốn sử dụng giao diện, hãy thử điều này.

[ClassInterface(ClassInterfaceType.None)] 
[ComSourceInterfaces(typeof(ICalculatorEvents))] 
[Guid("87457845-945u48-4954")] 
public class Calculator : ICalculator 
{ 
    public ICalculatorEvents callbackObject ; 

    public Add(int Num1, int Num2) 
    { 
     int Result = Num1 + Num2; 
     if(callbackObject != null) 
      callbackObject.Completed(Result); 
    } 
} 

và thay đổi _tmain() phương pháp này.

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CoInitialize(NULL); 
    Flag = 0; 

    EventHandler evh ; 
    ICalculatorPtr pCalc(__uuidof(Calculator)); 
    pCalc->callbackObject = &evh ; 
    pCalc->Add(5, 6); 

    do 
    { 
    }while(Flag == 0); 

    CoUninitialize(); 
    return 0; 
} 
0

tôi thấy rằng khởi COM trong C++ khách hàng nên được thực hiện sử dụng

CoInitializeEx(NULL, COINIT_MULTITHREADED); 

cho việc xử lý sự kiện không đồng bộ từ C# (.NET) COM máy chủ, nếu không C++ client nhận các sự kiện chỉ sau CoUninitialize() gọi .

Sự kiện xử lý lớp:

class EventWrapper : public IDispEventSimpleImpl<1, EventWrapper, &DIID_RumCardCOMEvents > 
    { 
    public: 
     // now you need to declare a sink map - a map of methods handling the events 
     BEGIN_SINK_MAP(EventWrapper) 
      SINK_ENTRY_INFO(1, DIID_RumCardCOMEvents, 0x1, isCardInserted, &cardInserted) 
      SINK_ENTRY_INFO(1, DIID_RumCardCOMEvents, 0x2, isCardRemoved, &cardRemoved) 
      // event interface id (can be more than 1)---+  |  |     | 
      // must match dispid of your event -----------------+  |     | 
      // method which handles the event ------------------------+     | 
      // type information for event, see below --------------------------------------+ 
     END_SINK_MAP() 

    // declare the type info object. You will need one for each method with different signature. 
     // it will be defined in the .cpp file, as it is a static member 
     static _ATL_FUNC_INFO cardInserted; // 'placeholder' object to carry event information (see below) 
     static _ATL_FUNC_INFO cardRemoved; // 'placeholder' object to carry event information (see below) 

     // method which handles the event 
     STDMETHOD (isCardInserted)(unsigned char type) 
     { 
      // usually it is defined it in the .cpp file 
      cout << "isCardInserted: " << (int)type << endl; 
      return 0; 
     } 

     STDMETHOD (isCardRemoved)() 
     { 
      // usually it is defined it in the .cpp file 
      cout << "isCardRemoved" << endl; 
      return 0; 
     } 
    }; 

chính:

int main() 
    { 
     CoInitializeEx(NULL, COINIT_MULTITHREADED); 
     try 
     { 
      EventWrapper ev; 
      ev.DispEventAdvise(/*COM interface*/); 
      // receiving events 
      ev.DispEventUnadvise(/*COM interface*/); 
     } 
     catch (_com_error& e) 
     { 
      cout << "Exception: " << e.ErrorMessage() << endl; 
     } 

     CoUninitialize(); 
     return 0; 
    } 
Các vấn đề liên quan