2013-06-25 3 views
3

Я прошел через tutorial of C# COM INterop. Выполнен демонстрационный пример, приведенный в ссылке успешно работает! Понимали все присутствующие там заявления, их смысл. И наткнулся the equivalent data types for c# objects.C# COM Interop: функция экспозиции с управляемым объектом как параметр

Я не мог найти хорошие книги (с примерами на C# COM Interop и призывающих COM компоненты из родной C++), кроме .NET и COM-взаимодействия Адама Натана и CCLI Nishant Шивакумара в действии. У меня нет проблем с регистрацией сборки и других вещей, но проблема с синтаксисом COM. Прежде чем объяснять мой код, я хотел понять, что такое VARIANT. Почему он там?

Это моя ситуация, у меня есть C класс #, как показано ниже:

using System.Text; 
using System.Runtime.InteropServices; 
using System.Drawing; 
namespace ManagedDLL 
{ 
    // Interface declaration. 
    [ComVisible(true), Guid("3265C537-E149-4559-B4E1-DBE334927DFA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface ICalculator 
    { 
     int Add(int Number1, int Number2); 
     int Subtract(Subtraction sb); 
    }; 
    // Interface implementation. 
    [ComVisible(true), Guid("0F50D3BE-CEEA-4C57-9882-4A609C7BB36C")] 
    public class ManagedClass : ICalculator 
    { 
     private int a, b; 
     public int Add(int Number1, int Number2) 
     { 
      return Number1 + Number2; 
     } 
     public int Subtract(Subtraction sub) 
     { 
      int a = 10, b = 3; 
      return sub.SubtractTwoNumbers(a, b); 
     } 

    } 
    [ComVisible(true)] 
    [Guid("C718EDDE-541C-4D15-B7EA-0533AB11A839")] 
    [ClassInterface(ClassInterfaceType.None)] 
    public class Subtraction 
    { 
     public int SubtractTwoNumbers(int a, int b) 
     { 
      return a - b; 
     } 

    } 
} 

получил .tlh файл после импорта файла TLB, как показано ниже:

#pragma once 
#pragma pack(push, 8) 

#include <comdef.h> 

namespace ManagedDLL { 

// 
// Forward references and typedefs 
// 

struct __declspec(uuid("4e5098b7-4e51-45e5-a705-a7e3c51e2a80")) 
/* LIBID */ __ManagedDLL; 
struct __declspec(uuid("3265c537-e149-4559-b4e1-dbe334927dfa")) 
/* interface */ ICalculator; 
struct /* coclass */ ManagedClass; 
struct /* coclass */ Subtraction; 
struct __declspec(uuid("c8e9181c-f064-3ec1-869e-042c6fdd3e46")) 
/* dual interface */ _ManagedClass; 

// 
// Smart pointer typedef declarations 
// 

_COM_SMARTPTR_TYPEDEF(ICalculator, __uuidof(ICalculator)); 
_COM_SMARTPTR_TYPEDEF(_ManagedClass, __uuidof(_ManagedClass)); 

// 
// Type library items 
// 

struct __declspec(uuid("3265c537-e149-4559-b4e1-dbe334927dfa")) 
ICalculator : IUnknown 
{ 
    // 
    // Raw methods provided by interface 
    // 

     virtual HRESULT __stdcall Add (
     /*[in]*/ long Number1, 
     /*[in]*/ long Number2, 
     /*[out,retval]*/ long * pRetVal) = 0; 
     virtual HRESULT __stdcall Subtract (
     /*[in]*/ struct _Object * sb, 
     /*[out,retval]*/ long * pRetVal) = 0; 
}; 

struct __declspec(uuid("0f50d3be-ceea-4c57-9882-4a609c7bb36c")) 
ManagedClass; 
    // [ default ] interface _ManagedClass 
    // interface _Object 
    // interface ICalculator 

struct __declspec(uuid("c718edde-541c-4d15-b7ea-0533ab11a839")) 
Subtraction; 
    // [ default ] interface _Object 

struct __declspec(uuid("c8e9181c-f064-3ec1-869e-042c6fdd3e46")) 
_ManagedClass : IDispatch 
{}; 

// 
// Named GUID constants initializations 
// 

extern "C" const GUID __declspec(selectany) LIBID_ManagedDLL = 
    {0x4e5098b7,0x4e51,0x45e5,{0xa7,0x05,0xa7,0xe3,0xc5,0x1e,0x2a,0x80}}; 
extern "C" const GUID __declspec(selectany) IID_ICalculator = 
    {0x3265c537,0xe149,0x4559,{0xb4,0xe1,0xdb,0xe3,0x34,0x92,0x7d,0xfa}}; 
extern "C" const GUID __declspec(selectany) CLSID_ManagedClass = 
    {0x0f50d3be,0xceea,0x4c57,{0x98,0x82,0x4a,0x60,0x9c,0x7b,0xb3,0x6c}}; 
extern "C" const GUID __declspec(selectany) CLSID_Subtraction = 
    {0xc718edde,0x541c,0x4d15,{0xb7,0xea,0x05,0x33,0xab,0x11,0xa8,0x39}}; 
extern "C" const GUID __declspec(selectany) IID__ManagedClass = 
    {0xc8e9181c,0xf064,0x3ec1,{0x86,0x9e,0x04,0x2c,0x6f,0xdd,0x3e,0x46}}; 

} // namespace ManagedDLL 

#pragma pack(pop) 

и, наконец, это мой родной C++ применение:

HRESULT hr = CoInitialize(NULL); 
ManagedDLL::ICalculatorPtr ptrInterface(__uuidof(ManagedDLL::ManagedClass)); 
IUnknown* pUnk=NULL; 
hr=CoCreateInstance(__uuidof(ManagedDLL::Subtraction), NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)pUnk); 
long lResult; 
ptrInterface->Subtract(pUnk, &lResult); //what should be written instead of pUnk, because it expects a _Object* as evident in the tlh file 
return lResult; 

Вопросы изобилие:

  1. Как получить доступ к методу Subtract в интерфейсе? Как нам создать экземпляр класса Subtraction, чей объект должен быть передан как параметр в этом методе Subtract?

  2. Как получить значение функции, возвращающей класс COM в качестве возвращаемого типа?

  3. Что такое IUnknown и IDispatch?

  4. И самое главное, почему _Object* был создан в качестве аргумента в файле COM .tlh вместо Subtraction* в качестве аргумента?

+1

Вот базовый C++ COM шаблонный код, который вы спрашиваете. Книга будет лучшим местом для поиска ответа на эти вопросы. –

ответ

2

Вопросы, которые вы задаете, - это классические фундаментальные вопросы о COM, которые могут взять небольшую книгу для ответа. Я бы посоветовал вам получить учебник или книгу о COM, которая принесет вам скорость. Вы не поймете взаимодействие, пока не поймете основы COM. Начните там, а затем пройдите через более сложные вещи.

Требуется некоторое серьезное время, чтобы ускориться по всем связанным с этим вопросам, поэтому не спешите!

Вот место, чтобы начать: http://msdn.microsoft.com/en-us/library/727z646z(v=vs.80).aspx

+0

Эй, @ed, можете ли вы рассказать мне, как подписаться на событие C#, представленное как COM в native C++. Я искал книгу Адама Натана в .NET и COM, но получил код клиента VB COM. Мне нужен пример C++. Я узнал о ключевых словах Advise и Unadvise и IConnectionPointPtr. Исследовали понятия, но не смогли найти ни одного примера! –