简体   繁体   English

C#COM Interop:使用托管对象作为参数公开函数

[英]C# COM Interop: exposing function with a managed object as parameter

I went through the tutorial of C# COM INterop . 我浏览了C#COM INterop教程 Performed the demo example given in the link successfully runs! 执行链接成功运行时给出的演示示例! Understood every statement present there, their meaning. 理解那里出现的每一个陈述,它们的含义。 And came across the equivalent data types for c# objects. 并且遇到了c#对象的等效数据类型。

I Couldn't find any good books (with examples on C# COM interop and calling COM components from native C++) apart from Adam Nathan's .NET and COM interoperability and Nishant Shivakumar's CCLI in Action. 除了Adam Nathan的.NET和COM互操作性以及Nishant Shivakumar的CCLI in Action之外,我找不到任何好书(有关C#COM互操作的示例和从本机C ++调用COM组件)。 I have no problems in registering assembly and other stuff but facing problems in COM syntax. 我在注册程序集和其他东西方面没有问题,但在COM语法中遇到问题。 Before explaining my code, I wanted to understand what VARIANT is. 在解释我的代码之前,我想了解VARIANT是什么。 Why is it there? 为什么会这样?

This is my situation, I have a C# class as below: 这是我的情况,我有一个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;
        }

    }
}

Got the .tlh file after importing tlb file as below: 导入tlb文件后得到.tlh文件,如下所示:

#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)

and finally this is my native C++ application: 最后这是我的原生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;

Questions galore: 问题丰富:

  1. How to access the Subtract method in the interface? 如何在界面中访问Subtract方法? How should we instantiate Subtraction class whose object should be passed as parameter in this Subtract method? 我们应该如何实例化Subtraction类,其对象应该作为Subtract方法中的参数传递?

  2. How to collect value of a function returning a COM class as return type? 如何收集返回COM类作为返回类型的函数的值?

  3. What are IUnknown and IDispatch ? 什么是IUnknownIDispatch

  4. And most importantly, why the _Object* was created as an argument in the COM .tlh file instead of Subtraction* as argument? 最重要的是,为什么_Object*被创建为COM .tlh文件中的参数而不是Subtraction*作为参数?

The questions you are asking are classical, fundamental questions about COM that could take a small book to answer. 你问的问题是关于COM的经典的基本问题,可能需要一本小书来回答。 I would suggest you get a tutorial or a book on COM that will bring you up to speed. 我建议你得到关于COM的教程或书籍,它会让你加快速度。 You won't understand the interop until you understand COM basics. 在了解COM基础知识之前,您不会理解互操作。 Start there, then work through the harder stuff. 从那里开始,然后通过更难的东西。

It takes some serious time to get up to speed on all the issues involved, so don't get in a hurry! 需要一些时间来加快所涉及的所有问题的速度,所以不要匆忙!

Here's a place to start: http://msdn.microsoft.com/en-us/library/727z646z(v=vs.80).aspx 这是一个开始的地方: http//msdn.microsoft.com/en-us/library/727z646z(v = vs。80).aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM