打通 C++ 和 C# 关于 COM 组件互相调用的任督二脉

文章出处:http://www.cppblog.com/free2000fly/archive/2009/03/23/77578.html

一. 关于从 C# 客户端调用 C++ 非托管代码的方法.

    本文不打算叙述, 参看以下文章. 
    http://www.codeproject.com/KB/cs/cominterop.aspx


二. 关于从 C++ 客户端调用 C# 托管代码的方法.

    (一). 非常直接的方法, 参看这篇文章. 
    http://www.codeproject.com/KB/cs/unmanagedtomanaged.aspx 

    源代码下载  http://www.cppblog.com/Files/free2000fly/cpp-call-cs.zip

    (二). 我们的方法. 这里主要讲我们的方法. 这里只讲实现过程, 不讲原理.

    1. C# 实现的组件 
        (1). 打开 VS 2008, 然后新建一个 C# 工程, 类型是 windows 的 class library, 工程名为 MyTestClsLib. 
             见下图  [--图1--] 

        (2). 打开 class1.cs 文件, 在 using System.Text; 语句后面添加语句
             using System.Runtime.InteropServices;

        (3). 将 public class Class1 类名改为更好认的, 如 SimpleType.

        (4). 在类 SimpleType 类头顶添加类接口属性 [ClassInterface(ClassInterfaceType.AutoDual)] 
             以上三步见下图  [--图2--] 


        (5). 在 SimpleType 类内部添加函数. 
            public string ConvertIntToString(int n) 
            { 
                return n.ToString(); 
            }

        (6). 打开工程的 AssemblyInfo.cs 文件, 将语句 
                [assembly: ComVisible(false)] 
            改为 
                [assembly: ComVisible(true)]

        (7). 打开工程的 "属性(properties)" 对话框. 选中 build 选项卡, 在这一页的最下边勾选 "Register for COM interop" 检查框. 
            见下图  [--图3--] 


        (8). 编译这个工程, 如果一切顺利, 将在 bin\debug\ 目录下生成目标文件 MyTestClsLib.dll 和 MyTestClsLib.tlb 文件.

        至此, C# 组件开发完毕. 通过查看注册表,可以看到增添了如下内容:

 

Windows Registry Editor Version  5.00

[ HKEY_CLASSES_ROOT\CLSID\{E57F961E-9925-3025-A854-AF3E4B7C0801} ]
@
= " MyTestClsLib.SimpleType "

[ HKEY_CLASSES_ROOT\CLSID\{E57F961E-9925-3025-A854-AF3E4B7C0801}\Implemented Categories ]
[ HKEY_CLASSES_ROOT\CLSID\{E57F961E-9925-3025-A854-AF3E4B7C0801}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29} ]
[ HKEY_CLASSES_ROOT\CLSID\{E57F961E-9925-3025-A854-AF3E4B7C0801}\InprocServer32 ]
@
= " mscoree.dll "
" ThreadingModel " = " both "
" Class " = " MyTestClsLib.SimpleType "
" Assembly " = " MyTestClsLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null "
" RuntimeVersion " = " v2.0.50727 "
" CodeBase " = " file:///E:/WUTemp/MyTestClsLib/bin/Debug/MyTestClsLib.dll "


[ HKEY_CLASSES_ROOT\CLSID\{E57F961E-9925-3025-A854-AF3E4B7C0801}\InprocServer32\1.0.0.0 ]
" Class " = " MyTestClsLib.SimpleType "
" Assembly " = " MyTestClsLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null "
" RuntimeVersion " = " v2.0.50727 "
" CodeBase " = " file:///E:/WUTemp/MyTestClsLib/bin/Debug/MyTestClsLib.dll "

[ HKEY_CLASSES_ROOT\CLSID\{E57F961E-9925-3025-A854-AF3E4B7C0801}\ProgId ]
@
= " MyTestClsLib.SimpleType "

[ HKEY_CLASSES_ROOT\MyTestClsLib.SimpleType ]
@
= " MyTestClsLib.SimpleType "

[ HKEY_CLASSES_ROOT\MyTestClsLib.SimpleType\CLSID ]
@
= " {E57F961E-9925-3025-A854-AF3E4B7C0801} "


    2. C++ 客户端的例子. 
        (1). 新建一个 C++ 控制台程序, 工程名字是 TestClient, 见下图  [--图4--] . 


        (2). 在包含文件 stdafx.h 内添加
            #include <windows.h>
            #include <atlbase.h>

        (3). 在 TestClient.cpp 文件添加如下内容. 
             #import "..\MyTestClsLib\bin\Debug\MyTestClsLib.tlb" raw_interfaces_only 
             using namespace MyTestClsLib;

        (4). 随便声明一个函数并实现之, 比如 void Foo(void); 在这个函数体内就可以调用我们先前实现的 C# 组件了. 
             比如这些代码:

            void Foo(void) 
            { 
                HRESULT hr = E_FAIL; 
                CComPtr<_SimpleType> spTmp; 
                hr = spTmp.CoCreateInstance(__uuidof(SimpleType)); 
                if (SUCCEEDED(hr)) 
                { 
                    CComBSTR str; 
                    spTmp->ConvertIntToString(887, &str); 
                } 
            }

        (5). 然后在 main 函数里就可以调用 Foo 函数了, 调用之前记得初始化 COM 环境. 见下图 [--图5--] . 


        (6). 到此, 打完收工. 现在, 就可以编译调试看看效果了. 看看 CComBSTR str 变量里是不是有了返回值 887? 

例子代码下载:  http://www.cppblog.com/Files/free2000fly/cstocpptest.zip

另一个例子, 用 C++ 的 ATL 定义接口, 然后用 C# 实现接口. 然后用 C++ 客户端来调用之. http://www.cppblog.com/Files/free2000fly/com2cs-impl.zip

 

参考资料:
   (1) http://www.codeproject.com/KB/cs/ManagedCOM.aspx
   (2) http://www.codeproject.com/KB/COM/cominterop.aspx
   (3) http://www.codeproject.com/KB/cs/cominterop.aspx
   (4) http://blogs.msdn.com/yizhang/archive/2007/11/05/net-mscoree-dll.aspx 
   (5) http://www.codeproject.com/KB/cs/unmanagedtomanaged.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值