找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 5831|回复: 67

VB.NET动态连接库使用四点总结和实例教程

[复制链接]
发表于 2017-3-11 16:26:54 | 显示全部楼层 |阅读模式

 VB.NET动态连接库还是比较常用的,于是我研究了一下,在这里拿出来和大家分享一下,希望对大家有用。Windows动态连接库是包含数据和函数的模块,可以被其它可执行文件(EXE、DLL、OCX 等)调用。动态连接库包含两种函数:输出(exported)函数和内部(internal)函数。输出函数可以被其它模块调用,而内部函数则只能在动态连接库内部使用。

  尽管VB.NET动态连接库也能输出 数据,但实际上它的数据通常是只在内部使用的。使用动态连接库的优点是显而易见的。将应用程序的一部分功能提取出来做成动态连接库,不但减小了主应用程序的大小,提高了程序 运行效率,还使它更加易于升级。多个应用程序共享一个动态连接库还能有效地节省系统资源。正因为如此,在Windows系统中,动态连接库得到了大量的使用。

  一般来说,动态连接库都是以DLL为扩展名的文件,如Kernel32.dll、commdlg.dll等。但也有例外,如16位Windows的核心部件之一GDI.exe其实也是一个动态库。编写动态连接库的工具很多,如VisualC++、BorlandC++、Delphi等,具体方法可以参见相关文档。下面只以Visual C++6.0为例,介绍一下开发应用于VisualBasic6.0的动态连接库时应注意的问题(本文中所有涉及C/C++语言或编译环境的地方,都以VC为例;所有涉及Visual Basic的地方都以VB 为例)。

  作为一种32位Windows应用程序的开发工具,VB生成的exe文件自然也都是32位的,通常情况下也只能调用32位的动态连接库。但是,并不是所有的32位动态库都能被VB生成的exe 文件正确地识别。一般来说,自己编写用于VB.NET动态连接库时,应注意以下几个方面的

  问题:

  1、生成动态库时要使用__stdcall调用约定,而不能使用缺省的__cdecl调用约定;__stdcall 约定通常用于32位API函数的调用。

  2、在VC中的定义文件(.def)中,必须列出输出函数的函数名,以强制VC系统将输出函数的装饰名(decoratedname)改成普通函数名;所谓装饰名是VC的编译器在编译过程中生成的输出函数名,它包含了用户定义的函数名、函数参数及函数所在的类等多方面的信息。由于在VC中定义文件不是必需的,因此工程不包含定义文件时VC就按自己的约定将用户定义的输出函数名修改成装饰名后放到输出函数列表中,这样的输出函数在VB生成的应用程序中是不能正确调用的(除非声明时使用Alias子句)。因此需要增加一个.def文件,其中列出用户需要的函数名,以强制VC不按装饰名进行输出。

  3、VC中的编译选项"结构成员对齐方式(structure member alignment)" 应设成4字节,其原因将在后文详细介绍。

  4、由于在C中整型变量是4个字节,而VB中的整型变量依然只有2个字节,因此在C中声 明的整型(int)变量在VB中调用时要声明为长整型(long),而C中的短整型(short)在VB中则 要声明成整型(integer);下表针对最常用的C语言数据类型列出了与之等价的Visual Basic 类型(用于32位版本的Windows)。


qq.jpg

1

主题

609

回帖

641

积分

软件网站元老会员

积分
641
发表于 2017-3-11 16:26:55 | 显示全部楼层
意,做了好几个店铺了,服务真心的不错,客服真的很热情,装修以后就是你家了!
 楼主| 发表于 2017-3-11 16:32:15 | 显示全部楼层
实例二

作为一种简单易用的Windows开发环境,Visual Basic从一推出就受到了广大编程人员的欢迎。它使程序员不必再直接面对纷繁复杂的Windows消息,而可以将精力主要集中在程序功能的实现上,大大提高了编程效率。但凡事有利必有弊。VB中高度的封装和模块化减轻了编程者的负担,同时也使开发人员失去了许多访问低层API函数和直接与Windows 交互的机会。因此,相比而言,VB应用程序的执行效率和功能比C/C++或Delphi生成的程序要差。为了解决这个问题,在一个大型的VB开发应用中,直接调用Windows API函数几乎是不可避免的;同时,还有可能需要程序员自己用C/C++等开发一些动态连接库,用于在VB调用动态连接库。本文主要讨论在32位开发环 境Visual Basic 5.0中直接调用Windows 95 API函数或用户生成的32位动态连接库的方法与规则。

Windows动态连接库是包含数据和函数的模块,可以被其它可执行文件(EXE、DLL、 OCX 等)调用。动态连接库包含两种函数:输出(exported)函数和内部(internal)函数。输出函数可以被其它模块调用,而内部函数则只能在动态连接库内部使用。尽管动态连接库也能输出 数据,但实际上它的数据通常是只在内部使用的。使用动态连接库的优点是显而易见的。将应用程序的一部分功能提取出来做成动态连接库,不但减小了主应用程序的大小,提高了程序运行效率,还使它更加易于升级。多个应用程序共享一个动态连接库还能有效地节省系统资源。正因为如此,在Windows系统中,动态连接库得到了大量的使用。

一般来说,动态连接库都是以DLL为扩展名的文件,如Kernel32.dll、 commdlg.dll等。但也有例外,如16位Windows的核心部件之一GDI.exe其实也是一个动态库。编写动态连接库的工具很多,如 VisualC++、BorlandC++、Delphi等,具体方法可以参见相关文档。下面只以Visual C++5.0为例,介绍一下开发应用于VisualBasic5.0的动态连接库时应注意的问题(本文中所有涉及C/C++语言或编译环境的地方,都以 VC5为例;所有涉及VisualBasic的地方都以VB5 为例)。

作为一种32位Windows应用程序的开发工具,VB5生成的exe文件自然也都是32位的,通常情况下也只能调用32位的动态连接库。但是,并不是所有的32位动态库都能被VB生成的exe 文件正确地识别。一般来说,自己编写用于VB调用动态连接库时,应注意以下几个方面的问题:

1、生成动态库时要使用__stdcall调用约定,而不能使用缺省的__cdecl调用约定;__stdcall 约定通常用于32位API函数的调用。

2、在VC5中的定义文件(.def)中,必须列出输出函数的函数名,以强制VC5系统将输出函数的装饰名(decoratedname)改成普通函数名;所谓装饰名是VC的编译器在编译过程中生成的输出函数名,它包含了用户定义的函数名、函数参数及函数所在的类等多方面的信息。由于在VC5中定义文件不是必需的,因此工程不包含定义文件时VC5就按自己的约定将用户定义的输出函数名修改成装饰名后放到输出函数列表中,这样的输出函数在VB生成的应用程序中是不能正确调用的(除非声明时使用Alias子句)。因此需要增加一个.def文件,其中列出用户需要的函数名,以强制VC5不按装饰名进行输出。

3、VC5中的编译选项"结构成员对齐方式(structure member alignment)" 应设成4字节,其原因将在后文详细介绍。

4、由于在C中整型变量是4个字节,而VB中的整型变量依然只有2个字节,因此在C中声明的整型(int)变量在VB中调用时要声明为长整型(long),而C中的短整型(short)在VB中则要声明成整型(integer);下表针对最常用的C语言数据类型列出了与之等价的Visual Basic 类型(用于32位版本的Windows)。

C语言数据类型在Visual Basic中声明为调用时使用的表达式
◆ATOM ByVal variable As Integer 结果为Integer 类型的表达式
◆BOOL ByVal variable As Long 结果为 Long 类型的表达式
◆BYTE ByVal variable As Byte 结果为 Byte 类型的表达式
◆CHAR ByVal variable As Byte 结果为 Byte 类型的表达式
◆COLORREF ByVal variable As Long 结果为 Long 类型的表达式
◆DWORD ByVal variable As Long 结果为 Long 类型的表达式
◆HWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄
◆INT, UINT ByVal variable As Long 结果为 Long 类型的表达式
◆LONG ByVal variable As Long 结果为 Long 类型的表达式
◆LPARAM ByVal variable As Long 结果为 Long 类型的表达式
◆LPDWORD variable As Long 结果为 Long 类型的表达式
◆LPINT, LPUINT variable As Long 结果为 Long 类型的表达式
◆LPRECT variable As type 自定义类型的任意变量
◆LPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式
◆LPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal)
◆LPWORD variable As Integer 结果为Integer 类型的表达式
◆LRESULT ByVal variable As Long 结果为 Long 类型的表达式
◆NULL As Any 或 ByVal Nothing 或
◆ByVal variable As Long ByVal 0& 或 VBNullString
◆SHORT ByVal variable As Integer 结果为Integer 类型的表达式
◆VOID Sub procedure 不可用
◆WORD ByVal variable As Integer 结果为Integer 类型的表达式
◆WPARAM ByVal variable As Long 结果为 Long 类型的表达式

5、VB中进行32位动态库的声明时,函数名是大小写敏感的。在获得了需要的动态连接库之后,就可以在VB调用动态连接库了。但是,由于VB不能验证应用程序传递到动态连接库中的参数值是否正确,因此VB程序中大量的API调用可能会降低整个应用程序的稳定性,也会增加以后维护的难度。所以,决定在VB程序中直接调用API函数时要慎重,但适当的使用API调用确实能够有效地提高VB程序的性能。这之间的平衡需要编程人员根据实际情况来掌握。下面就具体介绍一下在VB中调用API函数时需要做的工作。


 楼主| 发表于 2017-3-11 16:33:44 | 显示全部楼层
  1. 实例二

  2. 大家知道吗?VB一般可以生成两种特殊的DLL,一个是ActiveX DLL和ActiveX Control(*.ocx)。这两种DLL都是VB支持的标准类型。这里主要就怎样编写VB.NET .DLL动态链接库文件分析讲解。

  3.   NewViewStudio的意见:
  4.   创建VB.NET .DLL只是COM组件,无法作为输出函数的DLL,其实这只是个错误的说法。其实MS非常狡猾,如果你是个VB疯狂发烧友的话,应该早就狂试出这种可以创建输出函数的DLL的方法。 VB 编译文件实际上采取了两次编译的方法,首先是调用C2.exe产生*.OBJ文件,然后调用Link.EXE连接。如果在LINK的时候添加EXPORT 选项,实际上是可以输出函数的。但是,在VB的工程选项中将这些屏蔽了。而且过分的是:VB在Build完成后会将OBJ文件删除,这样就无法手动通过 Link来创建我们需要的DLL了。不过我找到一个比较龌鹾的变通的方法,就是先创建一个Exe工程,在Form_Load事件里面写下面的语句:

  5.   复制内容到剪贴板 VB.NET .DLL程序代码


  6.   
  7.   Sub Main  If MsgBox("哈哈", vbOKCancel) = vbOK Then Shell "link2.exe " & Command$ End If   
  8.   End Sub
  9.   然后编译为LinkTemp.EXE,接下来将LINK.EXE改名为Link2.exe,将LinkTemp.EXE改名为Link.EXE。这样在VB调用Link.EXE时会弹出对话框,处理就会中断。这时就可以有机会将OBJ文件拷贝出来了。  然后我创建了一个ActiveX DLL工程,在这个工程里面添加一个Module并创建一个Public函数mathadd:

  10.   复制内容到剪贴板 程序代码


  11.   
  12.   Public Function mathadd(ByVal a As Long, ByVal b As Long) As Long mathadd = a + b   
  13.   End Function   
  14.   编译这个工程,在Link的时候就会中断。然后把创建的Class1.obj、Module1.obj、Project1.obj备份出来。 然后就可以调用Link2.exe连接OBJ到DLL了,我的连接代码是:


  15.   
  16.   Link2.exe "e:\vbdll\Class1.obj" "e:\vbdll\Module1.obj" "e:\vbdll\Project1.obj"
  17.   "E:\Program Files\Microsoft Visual Studio\VB98\VBAEXE6.LIB" /ENTRY:__vbaS/EXPORT:mathadd/OUT:
  18.   "e:\vbdll\ProjectOK.dll" /BASE:0x11000000 /SUBSYSTEM:WINDOWS,4.0 /VERS   
  19.   注意里面的/ENTRY和/EXPORT开关,/EXPORT开关声明了输出函数mathadd。这样就大功告成了,可以被其他语言引入,例如在VB中,只需要:
复制代码

0

主题

901

回帖

1105

积分

软件网站中级元老会员

积分
1105
发表于 2017-3-11 20:47:07 | 显示全部楼层
家,很有信誉,好评

0

主题

616

回帖

594

积分

软件网站元老会员

积分
594
发表于 2017-3-13 19:54:43 | 显示全部楼层
。服务不错

45

主题

1299

回帖

3318

积分

abc

积分
3318
发表于 2017-3-13 20:19:09 | 显示全部楼层
很好,服务很好,耐心细致,下次还会来的

0

主题

557

回帖

582

积分

软件网站元老会员

积分
582
发表于 2017-3-13 21:11:32 | 显示全部楼层
力.服务很到位!

0

主题

571

回帖

594

积分

软件网站元老会员

积分
594
发表于 2017-3-14 11:52:56 | 显示全部楼层
根本不按我的意思来修改了一遍又一遍

0

主题

870

回帖

1018

积分

软件网站中级元老会员

积分
1018
发表于 2017-3-15 08:36:54 | 显示全部楼层
谢卖家,以后朋友需要会介绍来亲店里的!赞!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|

GMT+8, 2026-10-21 22:25

安卓脚本软件 · 键鼠盒子 · HID · 机械臂

快速回复 返回顶部 返回列表

随机阅读 · 更多好帖