如何通过类型库使 C DLL 更易于通过 VB 进行访问

如何通过类型库使 C DLL 更易于通过 VB 进行访问

文章编号:189133
最后修改:2006年5月24日
修订:4.1

概要

自 Visual Basic 首次发布之日起,它便提供了 Declare 语句作为利用以其他语言(如 C 语言)编写的 DLL 函数的方式。但是 Declare 语句并不完美,它通常需要您像熟悉 Visual Basic 代码一样了解有关 DLL 的信息。类型库创建了一种更加 Visual Basic 友好的方式来调用导出的 C 函数。

本文阐述如何在生成 DLL 时创建类型库,以及如何从 Visual Basic 中引用该库。

回到顶端

更多信息

类 型库是一些在自动化中使用的复合文档文件(.tlb 文件)。它们包含自动化服务器向其客户端公开的有关类型、对象、模块和接口的重要信息。幸运的是,服务器并不需要支持自动化功能便可利用类型库。实际上, 多数 C DLL 并不是自动化服务器,它们只需将其函数声明为类型库中的模块的成员。然后,诸如 Visual Basic 的自动化客户端便可读取并绑定到此信息,就如同它处理任何对象一样。您无需使用 Declare 语句,亦无需花费精力来记住那些常量,Visual Basic 会为您完成所有工作。

为 DLL 创建类型库有多项优点。最重要的是它可以增强类型的安全性。同时,由于 Visual Basic 可使用早期绑定自动绑定到您的函数,您还可以获得更佳的性能。与此相比,所有 Declare 语句都是晚期绑定的。此外,您还可以更好地控制将 DLL 提供给 Visual Basic 编程人员的方式。类型库允许您为函数和参数提供 Visual Basic 友好名称以及枚举、用户定义的类型 (UDT) 等其他有用内容。

目前,类型库通过用接口定义语言 (IDL) 或对象描述语言 (ODL) 编写的脚本创建。然后您可以使用 Visual Studio 附带的 MkTypLib.EXE 或 MIDL.EXE 对这些脚本进行编译。Visual C++ 可省去部分类型库创建工作,这是因为在您编译项目时,与 DLL 项目关联的任何 ODL 文件都将自动通过 MIDL 进行编译。

回到顶端

分步示例 — 创建 DLL 和类型库

1.打开 Visual C++ 5.0,然后选择“文件”|“新建”。在“项目”选项卡上,选择“Win32 动态链接库”并将项目命名为“TLBSamp”。
2.再次选择“文件”|“新建”。在“文件”选项卡上,选择“C++ 源文件”并将文件命名为“TLBSamp.c”,然后按“确定”。
3.再次重复步骤 2,并在这一次选择“文本文件”作为文件类型。分别将文件命名为“TLBSamp.def”和“TLBSamp.odl”。
4.接下来,将以下代码添加到 TLBSamp.c 中:
      #include <windows.h>

// MyDll_ReverseString -- Reverses the characters of a given string
void __stdcall MyDll_ReverseString(LPSTR lpString)
{
_strrev(lpString);
}

// MyDLL_Rotate -- Returns bit rotation of 32-bit integer value
int __stdcall MyDll_Rotate(int nVal, int nDirect, short iNumBits)
{
int nRet = 0;

if((iNumBits < 1) || (iNumBits > 31))
return nRet;

switch(nDirect)
{
case 0:
// Rotate nVal left by iNumBits
nRet = (((nVal) << (iNumBits)) |
((nVal) >> (32-(iNumBits))));
break;
case 1:
// Rotate nVal right by iNumBits
nRet = (((nVal) >> (iNumBits)) |
((nVal) << (32-(iNumBits))));
break;
}

return nRet;
}

5.为使函数成为可导出函数,请将以下代码添加到 TLBSamp.def 中:
      LIBRARY TLBSamp
DESCRIPTION 'Microsoft KB Sample DLL'
EXPORTS
MyDll_ReverseString
MyDll_Rotate

6.将以下代码添加到 TLBSamp.odl 中,从而在类型库中声明函数:
      // This is the type library for TLBSamp.dll
[
// Use GUIDGEN.EXE to create the UUID that uniquely identifies
// this library on the user's system. NOTE: This must be done!!
uuid(F1B9E420-F306-11d1-996A-92FF02C40D32),
// This helpstring defines how the library will appear in the
// References dialog of VB.
helpstring("KB Sample: Make your C DLL More Accessible"),
// Assume standard English locale.
lcid(0x0409),
// Assign a version number to keep track of changes.
version(1.0)
]
library TLBSample
{

// Define an Enumeration to use in one of our functions.
typedef enum tagRotateDirection
{
tlbRotateLeft=0,
tlbRotateRight=1
}RotateDirection;

// Now define the module that will "declare" your C functions.
[
helpstring("Sample functions exported by TLibSamp.dll"),
version(1.0),
// Give the name of your DLL here.
dllname("TLBSamp.dll")
]
module MyDllFunctions
{

[
// Add a description for your function that the developer can
// read in the VB Object Browser.
helpstring("Returns the reverse of a given string."),
// Specify the actual DLL entry point for the function. Notice
// the entry field is like the Alias keyword in a VB Declare
// statement -- it allows you to specify a more friendly name
// for your exported functions.
entry("MyDll_ReverseString")
]
// The [in], [out], and [in, out] keywords tell the Automation
// client which direction parameters need to be passed. Some
// calls can be optimized if a function only needs a parameter
// to be passed one-way.
void __stdcall ReverseString([in, out] LPSTR sMyString);

[
helpstring("Rotates a Long value in the given direction."),
entry("MyDll_Rotate")
]
// Besides specifying more friendly names, you can specify a more
// friendly type for a parameter. Notice the Direction parameter
// has been declared with our enumeration. This gives the VB
// developer easy access to our constant values.
int __stdcall BitRotate([in] int Value,
[in] RotateDirection Direction,
[in] short Bits);

} // End of Module
}; // End of Library

7.通过选择“生成”菜单中的“全部重新生成”,对 DLL 和类型库进行编译。完成编译后,将新的 DLL (TLBSamp.dll) 复制到 Visual Basic 目录中,以进行测试。
注意:为方便起见,您可能希望将类型库作为资源包括到 DLL 中。这样便可免于向每一位 Visual Basic 开发人员分发单独的 TLB 文件。

要将库作为资源添加,请完成以下步骤:
1.选择“文件”|“新建”。在“文件”选项卡上,选择“文本文件”并将文件命名为“TLBSamp.rc”,然后按“确定”。
2.在显示的文本窗口中,添加下面的一行内容:

1 typelib TLBSamp.tlb
3.保存文件并重新编译 DLL。完成后,将新的 DLL (TLBSamp.dll) 复制到 Visual Basic 目录中以进行测试;如果出现提示,请覆盖以前的文件。

回到顶端

分步示例 — Visual Basic 测试应用程序

1.要对 DLL 和类型库进行测试,请打开 Visual Basic 5.0 并创建一个新的标准项目。默认情况下会创建 Form1。
2.在“项目”菜单中,选择“引用” 以打开“引用”对话框,然后单击“浏览”找到您的新类型库(或 DLL,如果您已将库作为资源添加)。找到之后,按“确定”。Visual Basic 将在您首次引用该库时自动注册该库。请确保您已在“引用”列表中选中该库(“KB 示例:使您的 C DLL 更易于访问”),然后关闭该对话框。
3.按 F2 键打开对象浏览器。注意,库 (TLBSamp) 已添加到 Visual Basic 项目中,现在您可以像调用本机 Visual Basic 函数一样调用您的函数。Visual Basic 甚至可以在开发人员向 BitRotate 函数中键入 Direction 参数时自动展开您的枚举下拉列表。
4.向 Form1 中添加一个 CommandButton,然后将以下代码添加到该按钮的 Click 事件中:
      Private Sub Command1_Click()
Dim n1 As Long, n2 As Long, nTmp As Long
Dim sTest As String, sMsg As String

sTest = "Hello World!"
n1 = 100

ReverseString sTest
sMsg = sTest & " | "
ReverseString sTest
sMsg = sMsg & sTest & vbCrLf

nTmp = BitRotate(n1, tlbRotateLeft, 2)
n2 = BitRotate(nTmp, tlbRotateRight, 2)
sMsg = sMsg & Str$(n1) & " : " & Str$(nTmp) & " : " & Str$(n2)

MsgBox sMsg
End Sub

5.现在,按 F5 键便可在 IDE 中运行 vb5allB 项目。

注意:如果您收到错误消息,可能是因为 Visual Basic 无法找到您的 DLL。请确保在运行测试应用程序之前,您已将该 DLL 复制到 Visual Basic 目录或系统路径中。

回到顶端

参考

有关 ODL 或 IDL 结构的其他信息,请参见以下 Microsoft Developer Network (MSDN) Library 文章:
标题:类型库和对象描述语言
标题:接口定义和类型库

有关其他信息,请参见以下 Microsoft 知识库文章:
143258 (http://support.microsoft.com/kb/143258/):如何在类型库中创建常量和 DLL 声明

122285 (http://support.microsoft.com/kb/122285/):如何将类型库作为资源添加到 .dll 和 .exe 文件中

142840 (http://support.microsoft.com/kb/142840/) INFO:导出 DLL 函数的 Visual Basic 要求

(c) Microsoft Corporation 1998,保留所有权利。供稿人:Microsoft Corporation 的 Richard R. Taylor

回到顶端


这篇文章中的信息适用于:
Microsoft Visual Basic 5.0 学习版
Microsoft Visual Basic 6.0 学习版
Microsoft Visual Basic 5.0 专业版
Microsoft Visual Basic 6.0 专业版
Microsoft Visual C++ 5.0 专业版
Microsoft Visual Basic 5.0 企业版

回到顶端

关键字: 
kbhowto KB189133

回到顶端

Microsoft 和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何 责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与 该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失 所导致的之损害、数据或利润不负任何责任。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值