C++非托管调用托管C#编写的Com

本文详细介绍了如何使用C#编写COM组件,并探讨了C++非托管代码调用这些托管COM组件的具体实现方式。包括接口函数的转换、异常处理及常见数据类型的封送对照。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用C#编写Com是如此的简单,比C++的ATL还要简单。但是当C++的非托管代码调用C#编写的托管Com时,接口函数变成什么样子了呢?

例如:C#中的接口如下定义:

    [Guid("FA1FD727-74C7-4434-95D4-B25BC82F709C")]
    public interface ICSharp
    {
        [DispId(1)]
        int ModifyInt(out int value);
        [DispId(2)]
        string name();
        [DispId(3)]
        int Count { get; set; }
    }

 

在C++中调用的ModifyInt为HRESULT ModifyInt(long* value, long* valRet);

也就是说在C#中定义的接口的参数和返回值都成了C++中的参数,而且由out 定义的参数,在C++中成了指针,C#中的int对应成了c++中的long,那么c++中的HRESULT 又是C#中的什么呢?

哦了,C#中抛出的异常便是C++中ModifyInt的返回值了!ok

 

再看第二个接口函数

C# : string name();

C++: HRESULT name(BSTR* valRet);

 

再看第三个接口属性,这个有些不同

C# : int Count { get; set; }
C++: HRESULT get_Count(long* value); 

         HRESULT put_Count(long pRetVal);

 

常用封送类型对应表:

C++类型

C#封送处理类型

备注

BSTR

[MarshalAs(UnmanagedType.BStr)] string或直接使用 string

string的默认封送类型就是BSTR,但是在结构体中直接使用string,会有乱码。

const BSTR

[MarshalAs(UnmanagedType. LPWStr)] string

 

ULONG

uint

 

UINT

uint

 

GUID

Guid

 

HWND

intptr

在调用COM接口时,需要将句柄强制转换成long型。

HIMAGELIST

intptr

在调用COM接口时,需要将句柄强制转换成long型。

VARIANT

object

 

IUnknown *

[MarshalAs(UnmanagedType.IUnknown)] object

 

IUnknown **

out IntPtr

 当需要在COM中生成一个对象时,必须用intptr类型获得其指针,如果用object的话,非托管对象无法访问托管对象的堆栈。

结构体指针

unsafe直接定义。

COM中应定义相同的结构体,填充数据后可调用Marshal.StructureToPtr将非托管结构体对应内存填充上

 

对用与dll中的dllregisterserver,在C# 中需标识[ComRegisterFunctionAttribute]

如:

[ComRegisterFunctionAttribute]
public static void ComRegisterServer(Type t)

可在注册com时,顺便调用此函数注册所需内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值