使用COM客户端调用.NET对象
2006-06-02 16:49
316 查看
COM客户端为非托管环境,.NET对象是一个ClassLibrary
需要开放给非托管程序调用的.NET类库,最好实现一个public接口,否则每个托管类.NETFramework会生成一个类接口(名称为 _类名 )供COM客户端调用。
COM客户端在使用.NET对象的COM包装时,与使用普通COM组件相同。
.NET类库示例如下:
using System;
using System.Runtime.InteropServices;
namespace AAServer
{
public interface IDumyWork
{
int Addfour( int number );
int square( int number );
}
/// <summary>
/// Summary description for Class1.
/// </summary>
[ClassInterface(ClassInterfaceType.None)]
public class Class1: IDumyWork
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
#region IDumyWork Members
public int Addfour(int number)
{
return number + 4;
}
public int square(int number)
{
return number * number;
}
#endregion
}
}
上面代码中IDumyWork是类库公开的接口,Class1则相当于COM类对象,[ClassInterface(ClassInterfaceType.None)]则说明不生上面所述Class1的类接口。
注册.NET对象为COM组件
AAServer类库编译成功后,使用命令:
Regasm AAServer.dll /tlb AAServer.tlb
将注册COM组件,同时生成类型库tlb文件,这个文件在COM客户端引用COM组件时会用到。
Regasm AAServer.dll /u ; 取消组件注册
组件注册后,在OLEVIEW中可以看到其类型库信息如下:
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: AAServer.tlb
[
uuid(1AAA3E1C-A476-312A-BE2A-139DAE694F04),
version(1.0),
custom(90883F05-3D28-11D2-8F17-00A0C9A6186D, AAServer, Version=1.0.2344.25362, Culture=neutral, PublicKeyToken=c982512fd89d5c69)
]
library AAServer
{
// TLib : // TLib : Common Language Runtime Library : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
importlib("mscorlib.tlb");
// TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("STDOLE2.TLB");
// Forward declare all types defined in this typelib
interface IDumyWork;
[
odl,
uuid(79A96F30-31B6-39D1-A834-804DCBB4CACC),
version(1.0),
dual,
oleautomation,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AAServer.IDumyWork)
]
interface IDumyWork : IDispatch {
[id(0x60020000)]
HRESULT Addfour(
[in] long number,
[out, retval] long* pRetVal);
[id(0x60020001)]
HRESULT square(
[in] long number,
[out, retval] long* pRetVal);
};
[
uuid(D99C7A9B-3B90-3080-89CE-A42665B9725E),
version(1.0),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AAServer.Class1)
]
coclass Class1 {
interface _Object;
[default] interface IDumyWork;
};
};
其中_Object是Class1的基类生成的类接口,与一般的COM组件类型库基本相同。
在OLEVIEW中object classes -> grouped by componect category -> .NET category中可以看到“AAServer.Class1”类打开后发现它不仅实现了IDumyWork,IUnknown,IDispatch接口外,还实现了IConnectionPointContainer,IManagedObject等接口。
为.NET类库添加强名称
这是要为.NET类库添加强名称并加入全局程序集缓存中,这样客户端在运行时,不必将.NET类库DLL拷到EXE目录下。
创建密钥对:
sn -k AAServer.snk
生成密钥对,并将AAServer.snk考到project目录下,在AssemblyInfo.cs文件中添加:
[assembly: AssemblyKeyFile(@"../../AAServer.snk")]
重新编译类库,重新用regasm注册为COM组件,同时生成tlb类型库
加入全局程序集缓存:
gacutil /i AAServer.dll
从全局程序集缓存删除:
gacutil /u AAServer
加入全局程序集缓存后可以从C:/Winnt/assembly目录中看到"AAServer"项
COM客户端代码示例如下:
#include "stdafx.h"
#import "../AAServer/bin/Debug/AAServer.tlb"
inline void TESTHR( HRESULT _hr )
{ if FAILED(_hr) throw _com_error(_hr); }
int _tmain(int argc, _TCHAR* argv[])
{
try
{
TESTHR( CoInitializeEx( NULL, COINIT_MULTITHREADED ) );
AAServer::IDumyWorkPtr pwork = NULL;
TESTHR( pwork.CreateInstance( "AAServer.Class1" ) );
printf( "%d/n", pwork->Addfour( 10 ) );
printf( "%d/n", pwork->square( 11 ) );
}
catch(_com_error e)
{
printf( "Exception:" );
printf( e.ErrorMessage() );
}
}
其中import语句引用的是刚才用regasm生成的COM类型库,使用类库的方法与使用普通COM组件并无差别
注意: 如果没有为.NET类库生成强名称并加入global assembly cache,那么pwork.CreateInstance( "AAServer.Class1" )会抛出"类型没有注册"的异常,除非将类库DLL考一份到EXE的目录下
需要开放给非托管程序调用的.NET类库,最好实现一个public接口,否则每个托管类.NETFramework会生成一个类接口(名称为 _类名 )供COM客户端调用。
COM客户端在使用.NET对象的COM包装时,与使用普通COM组件相同。
.NET类库示例如下:
using System;
using System.Runtime.InteropServices;
namespace AAServer
{
public interface IDumyWork
{
int Addfour( int number );
int square( int number );
}
/// <summary>
/// Summary description for Class1.
/// </summary>
[ClassInterface(ClassInterfaceType.None)]
public class Class1: IDumyWork
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
#region IDumyWork Members
public int Addfour(int number)
{
return number + 4;
}
public int square(int number)
{
return number * number;
}
#endregion
}
}
上面代码中IDumyWork是类库公开的接口,Class1则相当于COM类对象,[ClassInterface(ClassInterfaceType.None)]则说明不生上面所述Class1的类接口。
注册.NET对象为COM组件
AAServer类库编译成功后,使用命令:
Regasm AAServer.dll /tlb AAServer.tlb
将注册COM组件,同时生成类型库tlb文件,这个文件在COM客户端引用COM组件时会用到。
Regasm AAServer.dll /u ; 取消组件注册
组件注册后,在OLEVIEW中可以看到其类型库信息如下:
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: AAServer.tlb
[
uuid(1AAA3E1C-A476-312A-BE2A-139DAE694F04),
version(1.0),
custom(90883F05-3D28-11D2-8F17-00A0C9A6186D, AAServer, Version=1.0.2344.25362, Culture=neutral, PublicKeyToken=c982512fd89d5c69)
]
library AAServer
{
// TLib : // TLib : Common Language Runtime Library : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
importlib("mscorlib.tlb");
// TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("STDOLE2.TLB");
// Forward declare all types defined in this typelib
interface IDumyWork;
[
odl,
uuid(79A96F30-31B6-39D1-A834-804DCBB4CACC),
version(1.0),
dual,
oleautomation,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AAServer.IDumyWork)
]
interface IDumyWork : IDispatch {
[id(0x60020000)]
HRESULT Addfour(
[in] long number,
[out, retval] long* pRetVal);
[id(0x60020001)]
HRESULT square(
[in] long number,
[out, retval] long* pRetVal);
};
[
uuid(D99C7A9B-3B90-3080-89CE-A42665B9725E),
version(1.0),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AAServer.Class1)
]
coclass Class1 {
interface _Object;
[default] interface IDumyWork;
};
};
其中_Object是Class1的基类生成的类接口,与一般的COM组件类型库基本相同。
在OLEVIEW中object classes -> grouped by componect category -> .NET category中可以看到“AAServer.Class1”类打开后发现它不仅实现了IDumyWork,IUnknown,IDispatch接口外,还实现了IConnectionPointContainer,IManagedObject等接口。
为.NET类库添加强名称
这是要为.NET类库添加强名称并加入全局程序集缓存中,这样客户端在运行时,不必将.NET类库DLL拷到EXE目录下。
创建密钥对:
sn -k AAServer.snk
生成密钥对,并将AAServer.snk考到project目录下,在AssemblyInfo.cs文件中添加:
[assembly: AssemblyKeyFile(@"../../AAServer.snk")]
重新编译类库,重新用regasm注册为COM组件,同时生成tlb类型库
加入全局程序集缓存:
gacutil /i AAServer.dll
从全局程序集缓存删除:
gacutil /u AAServer
加入全局程序集缓存后可以从C:/Winnt/assembly目录中看到"AAServer"项
COM客户端代码示例如下:
#include "stdafx.h"
#import "../AAServer/bin/Debug/AAServer.tlb"
inline void TESTHR( HRESULT _hr )
{ if FAILED(_hr) throw _com_error(_hr); }
int _tmain(int argc, _TCHAR* argv[])
{
try
{
TESTHR( CoInitializeEx( NULL, COINIT_MULTITHREADED ) );
AAServer::IDumyWorkPtr pwork = NULL;
TESTHR( pwork.CreateInstance( "AAServer.Class1" ) );
printf( "%d/n", pwork->Addfour( 10 ) );
printf( "%d/n", pwork->square( 11 ) );
}
catch(_com_error e)
{
printf( "Exception:" );
printf( e.ErrorMessage() );
}
}
其中import语句引用的是刚才用regasm生成的COM类型库,使用类库的方法与使用普通COM组件并无差别
注意: 如果没有为.NET类库生成强名称并加入global assembly cache,那么pwork.CreateInstance( "AAServer.Class1" )会抛出"类型没有注册"的异常,除非将类库DLL考一份到EXE的目录下
相关文章推荐
- 使用.NET2.0编写COM组件供VB调用
- OPC客户端调用时提示“无法将类型为“System.__ComObject”的 COM 对象强制转换为接口类型”...
- COM套间对.NET程序使用COM对象的影响(下)
- .NET中如何在调用COM时得到返回参数值System.Type.InvokeMember的使用
- .net中调用com对象的一个错误
- COM套间对.NET程序使用COM对象的影响
- 注册并发布一个xmlrpc远程对象(函数、类对象、客户端使用调用(对象.方法)格式)
- Memcached 使用 及.NET客户端调用 (资料整理)
- COM套间对.NET程序使用COM对象的影响(中)
- Memcached 使用 及.NET客户端调用
- java使用AXIS调用.net的webservice的小说明(webservice方法里含有对象)
- .NET调用外部接口将得到的List数据,并使用XmlSerializer序列化List对象成XML格式
- .net与java 使用自定义对象通过WebService调用
- 如何生成可从 COM 客户端调用的 .NET 服务器
- 【使用.NET2.0 编写COM组件供Visual Basic调用】
- 使用jacob调用Windows的com对象,转换Office文件为pdf、html等
- 使用.NET2.0编写COM组件供VB调用
- 如何从客户端 JavaScript 调用 .NET Web 服务使用 InternetExplorer 和 MSXML
- COM套间对.NET程序使用COM对象的影响(上)
- 客户端通过Ajax调用后台方法返回DataSet,Ilist,ilist,T,对象