制作vb dll的总结
前段時間,同學接了一個項目,在網頁上顯示autoCAD的圖。在做項目的過程中,遇到一個棘手的問題。在使用vb語言開發的第三方插件中,有一個函數是地址傳值的方式傳參。想在js中調用該函數,但是,js不支持類似指針的概念。后來在網上百度,發現可以使用dll封裝的方式解決該問題。即把這個ocx(插件)用Activex封裝一層。 JavaScript –> ActiveX –> 第三方ocx。??做一個ActiveX來調用第三方ocx,給它來個引用傳遞就行了。詳見:http://blog.sina.com.cn/s/blog_704d0c1c0100mft7.html
?
在制作該dll的過程中,遇到了很多問題。開發環境為vb。首先打開vb,選擇新建AvtiveX dll。在出來的界面中編寫代碼。
dll是一個函數庫,他不能獨立運行,沒有main函數。但是dll有一個dllMain函數,該該函數即為該dll的入口函數。如果缺少該入口函數,那么該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入口函數后,又出現了問題,即在調用dll中的函數時在js報“對象不支持此屬性或方法的錯誤”。經過一番調試,找到了錯誤所在,DllMain函數沒有處理線程加載的情況。修改DllMain函數
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文件的編譯,參考:
?
?
轉帖]?VB創建能作為輸出函數的DLL
DLL,?函數,?輸出
QQ:594363468
?
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?'將命令行復制到剪貼板?
????????'去掉?復制到剪貼板?LINK??速度會快些?
????????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("請輸入?輸出的函數名稱(對個函數?請用英文半角分號“;”分開)",?_?
????????????????"非法操作出錯我不管")?'模塊內能編譯出來的輸出函數名?
????????????????'修改命令行?
????????????????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?
'大家可能看出來了,??沒錯??就是在每個輸出函數前加/EXPORT:?
?
????生成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(String,vbUnicode?)返回時StrConv(String,vbFromUnicode?)
?
學了這個,大家不知道有沒有什么心得呢,當然這個要看個人悟性的問題。師父領進門,修行在個人嘛,何況還是被我這種半調子的菜鳥教呢
?
這個...天好藍...水好清...外掛...Winsock...API...DLL...監視API的值...修改...嘿嘿...我什么都沒說
?
如果遇到不懂的地方...就來問我啊...QQ:594363468
?
?
?
?
?
?
?
dll的注冊:在cmd中執行Regsvr32 *.dll
注冊之后即可使用。
查看ProggId 的方法:
在網上下載一個叫OLEVIEW的軟件,在其中查找你的dll注冊信息。一般來講,你的dll應該在Automation ?Objects中,名字和你做dll時的工程名一樣
?
?
轉載于:https://www.cnblogs.com/elnino/archive/2013/01/13/2858635.html
總結
以上是生活随笔為你收集整理的制作vb dll的总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基本java,jquery异步 的级联下
- 下一篇: day02(下)_运算符