用vb做了一个dll文件,在其他语言中调用的问题(追50分)

2025-02-23 23:04:52
推荐回答(5个)
回答1:

给你一个参考:
http://hi.baidu.com/aa64201205/blog/item/fe2b3418b183fa0e35fa41a5.html

回答2:

DLL文件(即Dynamic Link Library,动态链接库)作为系统的一个重要的组成部分,除了一些小程序外,我们几乎能在所有软件中看到DLL文件,而且如果使用VB写的一些收费软件有一个DLL代替关键函数,想破解都难了。因此,我们就有必要来学习如何编写DLL。
对于很多初学VB的网友来说,VB是一门比较简单的语言,而MicroSoft公司在开发VB时,也增添了很多功能。所以,我个人觉得VB除了部分不足之外还是挺不错的,当然我指的不足是主要是VB运行库方面的问题。
对于很多VB初学者来说,都会有这么一个错误的认识——VB中创建的DLL只是COM组件,无法作为输出函数的DLL(即VB写的DLL是不完整的DLL)。然而,对于一些VB的高手来说,他们就知道应该如何写具有返回值的DLL。其实,国外早已经有人做出了在VB中制作标准DLL的Add-Ins了,而且在网上也有对于写VB创建能作为输出函数的DLL的相关文章。今天,我再来讲讲这个话题——VB创建能作为输出函数的DLL

对于VB编写DLL,按照我的经验,主要分为两步:一、“安内”,二、“攘外”

首先,“攘外必先安内”
我们要知道如何使DLL拥有一个能被调用的API函数。很简单,我不想多说,就是在Module里面写一个Public的Function

接下来,我们就可以“攘外”了

那么,先来介绍一下编译技术

编译器的编译技术可以分为Native Compile(自然编译)与P-Code Compile(伪编译)两种。
自然编译是编译器将高级语言转换为汇编代码,并经链接生成EXE程序的过程。
伪编译是编译器将高级语言转换为某种编码后,将能解释、执行此编码的一段程序一同链接,生成EXE程序。
伪代码P-Code,最早应该叫做Pascal-Code,其名称起源于一个Pascal编译器使用的“中间代码”编译技术。现在一般作为Pseudo-code(伪代码)或Packed-code(压缩代码)简称。
采用伪代码编译时,每个VB源文件(包括.frm(窗体)、.bas(标准模块)、.cls(类模块))经VB IDE编译后各自生成相应的.obj文件,交链接程序Link.exe生成伪编译的可执行文件(EXE、DLL、OCX等)。
而用自然编译时,每个VB源文件由C2.exe编译生成汇编代码,生成相应的obj文件,再由Link.exe链接成为完整的可执行文件。

别看编译只有两步,其实,有大玄奥在里头。。。
MicroSoft公司,可以说是十分的狡猾,因为在默认的方式下,VB编译的两步使用到的命令行都是他们设定好的,所以,跳过了很多有用的部分,包括我们今天讲的输出函数部分。如果在LINK的时候添加EXPORT选项,实际上是可以输出函数的。但是,在VBLinkd的命令行中将这个选项部分跳过了。而且过分的是:VB在构造EXE后会将编译出来的OBJ文件删除,这样就无法手动通过Link来创建我们需要的DLL了。

我在网上看了些文章,最后选了一个比较龌龊的方法来变通

打开“VB6.0”,新建一个“标准EXE 工程”,把Form移除,添加一个Module
在模块里输入一下代码:

Sub Main()
If Command = "" Then Exit Sub '命令行不为空
Dim intCMD As Integer
Clipboard.Clear '清空剪贴板
Clipboard.SetText Command '将命令行复制到剪贴板
intCMD = MsgBox("编译命令行如下:" & vbCrLf & Command & vbCrLf & "点击“是”继续编译,点击“否”编译DLL,点击“取消”中断编译", vbYesNoCancel + vbInformation, "编译")
Select Case intCMD
Case vbYes '选择“是” 继续编译
Shell "VBLINK " & Command, vbHide
Case vbNo '选择“否”
Dim FuncName As String, cmd As String, l As Integer
FuncName = InputBox("请输入 输出的函数名称", "输出函数") '模块内能编译出来的输出函数名
'我试验了很多遍都只能拥有一个输出函数,我知道是命令行的问题,可是每次都加载DLL错误,郁闷死
'修改命令行
l = InStr(Command, "vbaS")
cmd = Left(Command, l + 4) & "/EXPORT:" & FuncName & Right(Command, Len(Command) - l - 3)
MsgBox cmd
Shell "VBLINK " & cmd, vbHide
Case vbCancel '中断编译
Exit Sub
End Select
End Sub

生成MyLink.exe,复制到VB的安装文件夹里,把安装文件夹的LINK.EXE改成VBLink.exe,把我们写的MyLink.exe改成Link.exe

到这一步,你应该懂了吧。。。

来做个示例

我新建了一个ActiveX DLL的工程,添加了一个Module,写了一个Public的Function,如下
Public Function Add(ByVal A As Long) As Long
Add = A + A
End Function

生成“E:\Math.dll”

被截获的命令行(VB默认命令行)如下:
"E:\Class1.OBJ" "E:\Module1.OBJ" "E:\Math.OBJ" "C:\Program Files\Microsoft Visual Studio\VB98\VBAEXE6.LIB" /ENTRY:__vbaS /OUT:"E:\Math.dll" /BASE:0x11000000 /SUBSYSTEM:WINDOWS,4.0 /VERSION:1.0 /DLL /INCREMENTAL:NO /OPT:REF /MERGE:.rdata=.text /IGNORE:4078

修改后命令行(修改后的命令行)如下:
"E:\Class1.OBJ" "E:\Module1.OBJ" "E:\Math.OBJ" "C:\Program Files\Microsoft Visual Studio\VB98\VBAEXE6.LIB" /ENTRY:__vbaS /EXPORT:Add /OUT:"E:\Math.dll" /BASE:0x11000000 /SUBSYSTEM:WINDOWS,4.0 /VERSION:1.0 /DLL /INCREMENTAL:NO /OPT:REF /MERGE:.rdata=.text /IGNORE:4078

大家对比两行命令可以发现在/ENTRY:_vbaS后面,我增加了/EXPORT:Add,这就是关键所在

现在,我又新建了一个EXE工程,加一个VB API声明,代码部分:

Private Declare Function Add Lib "E:\Math.dll" (ByVal A As Long) As Long 'API声明

Private Sub Form_Load()
MsgBox Add(2)
End Sub

看到效果没,成功了吧,别激动,如果你在工程里写的是String的内容,你会被活活气死,乱码会让你想自杀,不过可以用StrConv转化一下...自己领悟吧。

学了这个,大家不知道有没有什么心得呢,当然这个要看个人悟性的问题。师父领进门,修行在个人嘛,何况还是被我这种半调子的菜鸟教呢

这个...天好蓝...水好清...外挂...Winsock...API...替换系统DLL...监视API的值...修改...控制...嘿嘿...我什么都没说

如果遇到不懂的地方...就来问我啊...QQ:594363468

在我深入研究后,发现String投递时需要转换成指针才能避免出错

回答3:

把dll放在程序的根目录下

回答4:

VB默认的情况下编译的是ActiveX DLL,即非标准DLL
所以在编译命令行中做一些修改
详细请到我百度空间里看一篇《VB 创建可作为输出函数的DLL》

回答5:

建议你去下载一个vbAdvance,active dll 感觉很不方便,要就做成动态链接库。直接申明就可以用了。