COM与.NET的互操作

COM与.NET的互操作
COM与.NET的互操作中从.NET调用COM组件,如果使用VS.NET将变得非常容易,你只需要在你的工程中,添加对应的COM引用,编译工具就在后台悄悄的把COM“变成”了.NET程序集。而从传统的语言调用调用.NET组件却不如那么方便了。所以,我整理了个人调试成功的几段程序希望对大家有一些帮助,好了废话少说进入正题。
 
一,从vbscript等脚本调用.net组件
首先我们可以写一个.NET dll如下
//the first file:netServer.cs 
using System;
using System.Reflection;
using System.Runtime.InteropServices;
 
[assembly: AssemblyKeyFile("key.snk")]
namespace CSharpServer
{         
            //缺省的是ClassInterfaceType.AutoDispatch,该方式下只生成dispatch接口
        //只能被使用script、VB等late binding方式的COM客户使用
        [ClassInterfaceAttribute(ClassInterfaceType.AutoDual)] 
        public class SharpObject
        {
                private string m_strName;
 
                public SharpObject(){}
 
                public string Name    //Property: Name, Get/Set
                {
                        get        {       return m_strName;       }
                        set        {       m_strName = value;      }
                }
        }
}
 
//the second file: test.vbs
Dim obj
Set obj = CreateObject("CSharpServer.SharpObject")
obj.Name = "Chang Ming"
MsgBox "My Name is " & obj.Name
 
对这两个文件按如下方式编译,为了清晰起见我们使用命令行工具(命令行工具环境可以从开始——>Microsoft Visual Studio .NET——>Visual Studio .NET 工具——>Visual Studio .NET 命令提示中进入)
1,生成密钥文件,用于给程序集强名称签名
sn -k key.snk
 
2,使用强名称签名,编译成类库,
csc /t:library netserver.cs
 
3,生成类型库
tlbexp netserver.dll /out:netserver.tlb
 
4,注册dll
regasm netserver.dll
 
5,移入gac全局程序集缓存
gacutil -i netserver.dll
 
6,调用测试脚本
wscript test.vbs
 
在这里有几个需要注意的地方,1,必须要给程序集签名,让它具有强名称。2,必须将使用regasm注册程序集,它将会在注册表中添加相应的项。3,必须将签名后的强名称程序集移入全局程序集缓存(gac)。4,必须要先安装scriptengine了,微软的脚本执行引擎。这是从脚本调用.net 程序集了,呵呵,很简单吧?J
 
二,从C/C++调用.NET组件
还是一段程序,呵呵,程序就是我的生命:)
//file1 name:netServer.cs
using System;
using System.Reflection;
using System.Runtime.InteropServices;
 
[assembly: AssemblyKeyFile("key.snk")]
namespace CSharpServer
{         
                  
            public interface IObject   //声明接口
            {
                        double Sub(double c,double d);
            }
 
//[ClassInterfaceAttribute(ClassInterfaceType.AutoDual)]
 
        public class SharpObject:IObject
        {
                private string m_strName;
 
                public SharpObject(){}
 
                public string Name    //Property: Name, Get/Set
                {
                        get        {       return m_strName;       }
                        set        {       m_strName = value;      }
                }
                       
                        public double Add(double a,double b)
                        {
                                    Console.WriteLine("the answer is {0}",a+b);
                                    return a+b;
                        }
                        public double Sub(double c,double d)  //实现接口方法
                        {
                                    Console.WriteLine("the answer is {0}",c-d);
                                    return c-d;
                        }
        }
}
 
 
//file2 name:  comclient.cpp
#include <windows.h>
#include <stdio.h>
#include <iostream.h>
#pragma warning (disable: 4278)
 
#import "netServer.tlb" no_namespace named_guids
 
int main(int argc, char* argv[])
{
   IObject *cpi = NULL;
   int retval = 1;
 
   // Initialize COM and create an instance of the InterfaceImplementation class:
   CoInitialize(NULL);
   HRESULT hr = CoCreateInstance(CLSID_SharpObject,
               NULL,
               CLSCTX_INPROC_SERVER,
               IID_IObject,
               reinterpret_cast<void**>(&cpi));
 
   if (FAILED(hr))
   {
      printf("Couldn''''t create the instance!... 0x%x/n", hr);
   }
   else
   {
    
         printf("Calling function./n");
              
          retval = 0;
                         cout<<"10-4="<<cpi->Sub(10,4)<<endl;
         printf("Returned from function./n");
    
         cpi->Release();//释放com对象
   }
 
   // Be a good citizen and clean up COM:
   CoUninitialize();
   return retval;
}
 
编译方法还是如前
1,生成密钥文件,用于给程序集强名称签名
sn -k key.snk
 
2,使用强名称签名,编译成类库,
csc /t:library netserver.cs
 
3,生成类型库 //这一步很重要
tlbexp netserver.dll /out:netserver.tlb
 
4,注册dll
regasm netserver.dll
 
5,移入gac全局程序集缓存
gacutil -i netserver.dll
 
6,编译测试程序
cl COMClient.cpp
7,执行comclient.exe
 
说明:
c/c++中调用com要麻烦一些,首先要调用COM库函数CoInitialize(NULL);进行初始化,然后调用HRESULT hr = CoCreateInstance(CLSID_SharpObject,
               NULL,
               CLSCTX_INPROC_SERVER,
               IID_IObject,
               reinterpret_cast<void**>(&cpi));
其中CLSID_SharpObject是SharpObject类(com类)的类ID它是由工具生成的用来唯一标识SharpObject类,IID_IObject唯一标识IObject接口,如果CoCreateInstance成功的创建了COM对象,那么FAILED(hr)将为false,得到com对象的指针后,就可以用它调用com对象中的方法了.
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值