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

  1<windows.h>
  2
  3#include <stdio.h>
  4
  5#include <iostream.h>
  6
  7#pragma warning (disable: 4278) 
  8
  9#import "netServer.tlb" no_namespace named_guids 
 10
 11int main(int argc, char* argv[]) 
 12
 13{ 
 14
 15IObject *cpi = NULL; 
 16
 17int retval = 1; 
 18
 19// Initialize COM and create an instance of the InterfaceImplementation class: 
 20
 21CoInitialize(NULL); 
 22
 23HRESULT hr = CoCreateInstance(CLSID_SharpObject, 
 24
 25NULL, 
 26
 27CLSCTX_INPROC_SERVER, 
 28
 29IID_IObject, 
 30
 31reinterpret_cast<void**>(&amp;cpi)); 
 32
 33if (FAILED(hr)) 
 34
 35{ 
 36
 37printf("Couldn't create the instance!... 0x%x\n", hr); 
 38
 39} 
 40
 41else 
 42
 43{ 
 44
 45printf("Calling function.\n"); 
 46
 47retval = 0; 
 48
 49cout&lt;&lt;"10-4="&lt;<cpi->Sub(10,4)&lt;<endl; cpi-="" from="" function.\n");="" printf("returned="">Release();//  释放  com  对象 
 50
 51} 
 52
 53// Be a good citizen and clean up COM: 
 54
 55CoUninitialize(); 
 56
 57return retval; 
 58
 59} 
 60
 61编译方法还是如前 
 62
 631,  生成密钥文件,用于给程序集强名称签名 
 64
 65sn -k key.snk 
 66
 672  ,使用强名称签名,编译成类库, 
 68
 69csc /t:library netserver.cs 
 70
 713  ,生成类型库  //  这一步很重要 
 72
 73tlbexp netserver.dll /out:netserver.tlb 
 74
 754  ,注册  dll 
 76
 77regasm netserver.dll 
 78
 795,  移入  gac  全局程序集缓存 
 80
 81gacutil -i netserver.dll 
 82
 836  ,编译测试程序 
 84
 85cl COMClient.cpp 
 86
 877  ,执行  comclient.exe 
 88
 89说明: 
 90
 91在  c/c++  中调用  com  要麻烦一些,首先要调用  COM  库函数  CoInitialize(NULL);  进行初始化,然后调用  HRESULT hr = CoCreateInstance(CLSID_SharpObject, 
 92
 93NULL, 
 94
 95CLSCTX_INPROC_SERVER, 
 96
 97IID_IObject, 
 98
 99reinterpret_cast<void**>(&amp;cpi)); 
100
101其中  CLSID_SharpObject  是  SharpObject  类(  com  类)的类  ID  它是由工具生成的用来唯一标识  SharpObject  类,  IID_IObject  唯一标识  IObject  接口,如果  CoCreateInstance  成功的创建了  COM  对象,那么  FAILED(hr)  将为  false,  得到  com  对象的指针后,就可以用它调用  com  对象中的方法了  . 
102
103欢迎喜欢  COM  和  .NET  的兄弟姐妹和我讨论,  MSN: [email protected]</void**></endl;></cpi-></void**></iostream.h></stdio.h></windows.h>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus