电竞比分网-中国电竞赛事及体育赛事平台

分享

制作vb dll的總結(jié)

 阿毅s6kc8rp1nf 2017-10-19

前段時間,同學(xué)接了一個項目,在網(wǎng)頁上顯示autoCAD的圖。在做項目的過程中,遇到一個棘手的問題。在使用vb語言開發(fā)的第三方插件中,有一個函數(shù)是地址傳值的方式傳參。想在js中調(diào)用該函數(shù),但是,js不支持類似指針的概念。后來在網(wǎng)上百度,發(fā)現(xiàn)可以使用dll封裝的方式解決該問題。即把這個ocx(插件)用Activex封裝一層。 JavaScript –> ActiveX –> 第三方ocx。  做一個ActiveX來調(diào)用第三方ocx,給它來個引用傳遞就行了。詳見:http://blog.sina.com.cn/s/blog_704d0c1c0100mft7.html

 

在制作該dll的過程中,遇到了很多問題。開發(fā)環(huán)境為vb。首先打開vb,選擇新建AvtiveX dll。在出來的界面中編寫代碼。

dll是一個函數(shù)庫,他不能獨立運行,沒有main函數(shù)。但是dll有一個dllMain函數(shù),該該函數(shù)即為該dll的入口函數(shù)。如果缺少該入口函數(shù),那么該dll在加載的時候即會報”找不到入口點

dllRegisterServer“的錯誤。

Public Function DllMain(ByVal hInst As Long, ByVal fdwReason As Long, ByVal lpvReserved As Long) As Boolean
Select Case fdwReason
Case DLL_PROCESS_DETACH
Case DLL_PROCESS_ATTACH
DllMain = True
Case DLL_THREAD_ATTACH
Case DLL_THREAD_DETACH
End Select
End Function

 

在添加了dllMain入口函數(shù)后,又出現(xiàn)了問題,即在調(diào)用dll中的函數(shù)時在js報“對象不支持此屬性或方法的錯誤”。經(jīng)過一番調(diào)試,找到了錯誤所在,DllMain函數(shù)沒有處理線程加載的情況。修改DllMain函數(shù)

Public Function DllMain(ByVal hInst As Long, ByVal fdwReason As Long, ByVal lpvReserved As Long) As Boolean
Select Case fdwReason
Case DLL_PROCESS_DETACH
Case DLL_PROCESS_ATTACH
DllMain = True
Case DLL_THREAD_ATTACH

DllMain=True

Case DLL_THREAD_DETACH
End Select
End Function

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

至于dll文件的編譯,參考:

 

 

轉(zhuǎn)帖] VB創(chuàng)建能作為輸出函數(shù)的DLL

DLL, 函數(shù)輸出

QQ594363468

 

DLL文件(即Dynamic Link Library,動態(tài)鏈接庫)作為系統(tǒng)的一個重要的組成部分,除了一些小程序外,我們幾乎能在所有軟件中看到DLL文件,而且如果使用VB寫的一些收費軟件有一個DLL代替關(guān)鍵函數(shù),想破解都難了。因此,我們就有必要來學(xué)習如何編寫DLL。

對于很多初學(xué)VB的網(wǎng)友來說,VB是一門比較簡單的語言,而MicroSoft公司在開發(fā)VB時,也增添了很多功能。所以,我個人覺得VB除了部分不足之外還是挺不錯的,當然我指的不足是主要是VB運行庫方面的問題。

對于很多VB初學(xué)者來說,都會有這么一個錯誤的認識——VB中創(chuàng)建的DLL只是COM組件,無法作為輸出函數(shù)的DLL(即VB寫的DLL是不完整的DLL)。然而,對于一些VB的高手來說,他們就知道應(yīng)該如何寫具有返回值的DLL。其實,國外早已經(jīng)有人做出了在VB中制作標準DLLAdd-Ins了,而且在網(wǎng)上也有對于寫VB創(chuàng)建能作為輸出函數(shù)的DLL的相關(guān)文章。今天,我再來講講這個話題——VB創(chuàng)建能作為輸出函數(shù)的DLL

 

對于VB編寫DLL,按照我的經(jīng)驗,主要分為兩步:一、“安內(nèi)”,二、“攘外”

 

首先,“攘外必先安內(nèi)”

我們要知道如何使DLL擁有一個能被調(diào)用的API函數(shù)。很簡單,我不想多說,就是在Module里面寫一個PublicFunction

 

接下來,我們就可以“攘外”了

 

那么,先來介紹一下編譯技術(shù)

 

編譯器的編譯技術(shù)可以分為Native Compile(自然編譯)與P-Code Compile(偽編譯)兩種。

    自然編譯是編譯器將高級語言轉(zhuǎn)換為匯編代碼,并經(jīng)鏈接生成EXE程序的過程。

    偽編譯是編譯器將高級語言轉(zhuǎn)換為某種編碼后,將能解釋、執(zhí)行此編碼的一段程序一同鏈接,生成EXE程序。

    偽代碼P-Code,最早應(yīng)該叫做Pascal-Code,其名稱起源于一個Pascal編譯器使用的“中間代碼”編譯技術(shù)?,F(xiàn)在一般作為Pseudo-code(偽代碼)或Packed-code(壓縮代碼)簡稱。

采用偽代碼編譯時,每個VB源文件(包括.frm(窗體)、.bas(標準模塊)、.cls(類模塊))經(jīng)VB IDE編譯后各自生成相應(yīng)的.obj文件,交鏈接程序Link.exe生成偽編譯的可執(zhí)行文件(EXE、DLLOCX等)。

    而用自然編譯時,每個VB源文件由C2.exe編譯生成匯編代碼,生成相應(yīng)的obj文件,再由Link.exe鏈接成為完整的可執(zhí)行文件。

 

別看編譯只有兩步,其實,有大玄奧在里頭。。。

MicroSoft公司,可以說是十分的狡猾,因為在默認的方式下,VB編譯的兩步使用到的命令行都是他們設(shè)定好的,所以,跳過了很多有用的部分,包括我們今天講的輸出函數(shù)部分。如果在LINK的時候添加EXPORT選項,實際上是可以輸出函數(shù)的。但是,在VBLinkd的命令行中將這個選項部分跳過了。而且過分的是:VB在構(gòu)造EXE后會將編譯出來的OBJ文件刪除,這樣就無法手動通過Link來創(chuàng)建我們需要的DLL了。

 

根據(jù)前人的方法,加上自己修改,用一個比較齷齪的方法來變通

 

打開“VB6.0”,新建一個“標準EXE 工程”,把Form移除,添加一個Module

在模塊里輸入一下代碼:

 

    Sub Main() 

        If Command = "" Then Exit Sub '命令行不為空 

        Dim intCMD As Integer 

        'Clipboard.Clear '清空剪貼板 

        'Clipboard.SetText Command '將命令行復(fù)制到剪貼板 

        '去掉 復(fù)制到剪貼板 LINK  速度會快些 

        intCMD = MsgBox("編譯命令行如下:" & vbCrLf & Command & vbCrLf & "點擊“是”繼續(xù)編譯,點擊“否”編譯DLL,點擊“取消”中斷編譯", vbYesNoCancel + vbInformation, "編譯") 

        Select Case intCMD 

            Case vbYes '選擇“是” 繼續(xù)編譯 

                Shell "VBLINK " & Command, vbHide 

            Case vbNo '選擇“否” 

                Dim FuncName As String, cmd As String, l As Integer 

                FuncName = InputBox("請輸入 輸出的函數(shù)名稱(對個函數(shù) 請用英文半角分號“;”分開)", _ 

                "非法操作出錯我不管") '模塊內(nèi)能編譯出來的輸出函數(shù)名 

                '修改命令行 

                If FuncName = "" Then Exit Sub 

                Do 

                    FuncName = Replace(FuncName, ";", " /EXPORT:") 

                Loop Until 0 = InStr(FuncName, ";") 

                l = InStr(Command, "vbaS") 

                cmd = Left(Command, l + 4) & "/EXPORT:" & FuncName & Right(Command, Len(Command) - l - 3) 

                Shell "VBLINK " & cmd, vbHide 

            Case vbCancel '中斷編譯 

                Exit Sub 

        End Select 

    End Sub 

'大家可能看出來了,  沒錯  就是在每個輸出函數(shù)前加/EXPORT: 

 

    生成MyLink.exe,復(fù)制到VB的安裝文件夾里,把安裝文件夾的LINK.EXE改成VBLink.exe,把我們寫的MyLink.exe改成Link.exe

 

    到這一步,你應(yīng)該懂了吧。。。

 

    來做個示例

 

我新建了一個ActiveX DLL的工程,添加了一個Module,寫了一個PublicFunction,如下

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 

 

大家對比兩行命令可以發(fā)現(xiàn)在/ENTRY:_vbaS后面,我增加了/EXPORT:Add,這就是關(guān)鍵所在

 

現(xiàn)在,我又新建了一個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(String,vbUnicode )返回時StrConv(String,vbFromUnicode )

 

學(xué)了這個,大家不知道有沒有什么心得呢,當然這個要看個人悟性的問題。師父領(lǐng)進門,修行在個人嘛,何況還是被我這種半調(diào)子的菜鳥教呢

 

這個...天好藍...水好清...外掛...Winsock...API...DLL...監(jiān)視API的值...修改...嘿嘿...我什么都沒說

 

如果遇到不懂的地方...就來問我啊...QQ594363468

 

 

 

 

 

 

 

dll的注冊:在cmd中執(zhí)行Regsvr32 *.dll

注冊之后即可使用。

查看ProggId 的方法:

在網(wǎng)上下載一個叫OLEVIEW的軟件,在其中查找你的dll注冊信息。一般來講,你的dll應(yīng)該在Automation  Objects中,名字和你做dll時的工程名一樣

 

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多