这部分描述了在托管代码中调用COM组件的方法,
现存的COM组件在托管代码中作为中间件或者独立的功能实体是很有价值的资源
向.NET Framework报露COM组件
1. Import a type library as an assembly
COM的类型定义通常在type library(tlb)中,与之对应的是CLS兼容的编译器在assembly中产生类型元数据(type metadata),这两种类型信息的来源有很大的不同
现存的COM组件在托管代码中作为中间件或者独立的功能实体是很有价值的资源
向.NET Framework报露COM组件
1. Import a type library as an assembly
COM的类型定义通常在type library(tlb)中,与之对应的是CLS兼容的编译器在assembly中产生类型元数据(type metadata),这两种类型信息的来源有很大的不同
Generating Metadata
COM
的类型库(
type libraries
)可以是一个单独得
Tlb
文件,例如
Loanlib.tlb
。一些类型库被嵌入到
DLL
或者
Exe
的资源文件中,还有一些类型库在
OLB
或者
OCX
中。
找到包含你的
COM
类型的类型库之后,可以有以下的选择来生成包含元数据的交互程序集(
interop assembly
)
Option
|
Description
|
Visual Studio .NET
|
Automatically converts COM types in a type library to metadata in an assembly.
|
Type Library Importer
|
Provides command-line switches to adjust metadata in the resulting interop file, imports types from an existing type library, and generates an interop assembly and a namespace.
|
TypeLibConverter Class
|
Exposes methods that perform conversion-related actions. Can convert in-memory type library information to metadata.
|
Custom Wrappers
|
As a less desirable option, you can create type definitions from scratch. This requires advanced programming skills.
|
当添加一个给定的
type library
的引用(
reference
)时,
Visual Studio .NET
生成包含元数据的交互程序集(
interop assembly
)。如果一个主交互程序集(
primary interop assembly
)有效的话,
Visual Studio
使用存在的
assembly
To add a reference to a type library
1. Install the COM DLL or EXE file on your computer, unless a Windows Setup.exe performs the installation for you.
2. From the Project menu, select References.
3. Select the COM tab.
4. Select the type library from the Available References list, or browse for the TLB file.
5. Click OK.
Type Library Importer
The Type Library Importer (Tlbimp.exe)
是一个命令行的工具,它可以把
COM
的类型库中的
Coclassed
和
interfaces
转换成元数据。
使用方法:
tlbimp Loanlib.dll
TypeLibConverter Class
TypeLibConverter class
(
in the System.Runtime.InteropServices namespace
)提供了转换类型库中的
coclasses
和
interfaces
到元数据的方法。
Custom Wrappers
当一个类型库不可用或者不正确时,一个可选的方法就是在托管代码重创建一个
class
或者
interface
定义的副本。然后编译代码在
runtime
在程序集中产生元数据
手动定义
COM
类型,必须遵循如下
•
准确的描述定义的
coclasses
和
interfaces
•
一个编译器,例如
C#
编译器可以生成对应的
.NET Framework
的类的定义
•
type library-to-assembly
转化规则的相关知识
写一个自定义的包装类(
wrapper
)是一项应该很少使用的高级的技术。
2. Using COM Types in Managed Code
COM
在程序集中类型定义类似其他的托管代码。托管的客户可以使用通常的方式创建
COM
类型的新的实例并且像其他托管类一样通过元数据得到类的信息。方法的语法可以通过
object viewer
或者反射(
reflection
)得到。当
COM
的方法返回一个失败的结果时,
.NET
的客户得到一个对应的异常。
得到或者释放一个运行的
COM
对象的引用像得到或者释放其他的运行的托管对象的引用一样。当一个
.NET
的客户端得到或者释放
COM
对象的引用,运行时像其他的
COM
客户端那样维护
COM
对象的引用计数,
.NET
的客户端可以认为对象可以像其他的托管对象那样被垃圾收集。
下面是
C#
的客户端代码
[C#]
using System;
using LoanLib;
public class LoanApp {
public static void Main(String[] Args) {
Loan ln = new Loan();
if (Args.Length < 4)
{
Console.WriteLine("Usage: ConLoan Balance Rate Term Payment");
Console.WriteLine(" Either Balance, Rate, Term, or Payment
must be 0");
return;
}
ln.OpeningBalance = Convert.ToDouble(Args[0]);
ln.Rate = Convert.ToDouble(Args[1])/100.0;
ln.Term = Convert.ToInt16(Args[2]);
ln.Payment = Convert.ToDouble(Args[3]);
if (ln.OpeningBalance == 0.00) ln.ComputeOpeningBalance();
if (ln.Rate == 0.00) ln.ComputeRate();
if (ln.Term == 0) ln.ComputeTerm();
if (ln.Payment == 0.00) ln.ComputePayment();
Console.WriteLine("Balance = {0,10:0.00}", ln.OpeningBalance);
Console.WriteLine("Rate = {0,10:0.0%}", ln.Rate);
Console.WriteLine("Term = {0,10:0.00}", ln.Term);
Console.WriteLine("Payment = {0,10:0.00}/n", ln.Payment);
bool MorePmts;
double Balance = 0.0;
double Principal = 0.0;
double Interest = 0.0;
Console.WriteLine("{0,4}{1,10}{2,12}{3,10}{4,12}", "Nbr", "Payment",
"Principal", "Interest", "Balance");
Console.WriteLine("{0,4}{1,10}{2,12}{3,10}{4,12}", "---", "-------",
"---------", "--------", "-------");
MorePmts = ln.GetFirstPmtDistribution(ln.Payment, out Balance,
out Principal, out Interest);
for (short PmtNbr = 1; MorePmts; PmtNbr++) {
Console.WriteLine("{0,4}{1,10:0.00}{2,12:0.00}{3,10:0.00}
{4,12:0.00}", PmtNbr, ln.Payment, Principal, Interest,
Balance);
MorePmts = ln.GetNextPmtDistribution(ln.Payment, ref Balance,
out Principal, out Interest);
}
}
}