本帖最后由 VBProFan 于 2010-4-29 16:21 編輯 全球首創(chuàng)? 全球再次突破VB極限! 只需在線程中加一行代碼實(shí)現(xiàn) VB 真正穩(wěn)定多線程 不需要... 1.不需要寫(xiě)tlb庫(kù)(感覺(jué)麻煩了,使用tlb主要是防止vb設(shè)置err.lastDllerr), 2.不需要處理tls(很多都是暴力copy,不知道有沒(méi)有后遺癥?) 3.不需要編譯成activx exe(這東東會(huì)在注冊(cè)表留下垃圾項(xiàng),從VB的引用中會(huì)看到), 4.不需要編譯成p-code(P代碼的壞處眾所周知了) 5.不需要干掉 setSysXXXerr(干掉后 err.lastDllErr肯定無(wú)效啦,不爽) 6.不需要遠(yuǎn)程創(chuàng)建線程...(汗,誰(shuí)發(fā)明的,好厲害,轉(zhuǎn)了好大一個(gè)圈) ...(還有沒(méi)有?) 俗話說(shuō)得好,有錢能使鬼推磨,果然不假... 此次的靈感來(lái)源于這1000塊大洋... http://www.vbgood.com/viewthread.php?tid=92649 (上面的代碼是使用P CODE實(shí)現(xiàn)的VB線程安全) 等你學(xué)會(huì)了全球首創(chuàng)大法后,就能把他改為本機(jī)代碼的線程安全.原代碼不需要用TLB再次封裝修改.
http://www.freevbcode.com/ShowCode.Asp?ID=4029 接下來(lái).用上面"全球首創(chuàng)"的方法改進(jìn)一下...
當(dāng)然了,仍有不足之處,暫時(shí)不說(shuō)(其實(shí)在別的貼子說(shuō)過(guò)了),留給大家去發(fā)現(xiàn)... 未完待續(xù)...(根據(jù)反應(yīng)的良好后再加以重點(diǎn)說(shuō)明.反應(yīng)不好的就不說(shuō)明了 ) PS:有錢的記得加錢,沒(méi)錢的記得加分啊~~~ 這樣才會(huì)繼續(xù)公開(kāi)VB內(nèi)幕... PPS:如果是mei nv也可以向老漢使mei ren計(jì),偶可是會(huì)中計(jì)滴... -----------------------下面是揭密---------------------------- 只需在線程中加一行代碼實(shí)現(xiàn) VB 真正穩(wěn)定多線程揭密 1.為什么要聲明成tlb庫(kù)的原因. 眾所周知,VB的函數(shù)包裝了API,舉例: 當(dāng)調(diào)用GetProcAddr時(shí),VB是用的DllCallFunction(好像是這個(gè)名吧?記不太清了)先檢查有沒(méi)有加載,有的話直接JMP過(guò)去,沒(méi)有的話又要執(zhí)行幾個(gè)API進(jìn)行加載. 同樣的,當(dāng)調(diào)用GetLastWin32Err(估計(jì)這是個(gè)名吧?記不太清)同樣的,又是經(jīng)過(guò)了幾個(gè)API.這時(shí)的錯(cuò)誤號(hào)己經(jīng)不是最初的那個(gè)API的錯(cuò)誤了.(可能己被覆蓋) 那么API出錯(cuò)怎么知道呢,調(diào)用源碼中聲明的API的時(shí)候,VB就自作聰明的在后面加上一句SetXXXErr(全名記不太清).這樣一來(lái).當(dāng)在多線程或回調(diào)中調(diào)用API時(shí).變成了下面這樣 DllCall MessageBox SetXXXErr err.LastDllError (這個(gè)err是個(gè)對(duì)象,保存winapi.GetLastError的值,免得被VB函數(shù)中調(diào)用的API覆蓋了錯(cuò)誤信息) 在一般情況下是正常的,在線程中由于這個(gè)err沒(méi)有初始化,所以就會(huì)保存錯(cuò)誤號(hào)到未初始化的內(nèi)存中.就出現(xiàn)線程錯(cuò)誤了. 用TLB時(shí)VB編譯后這個(gè)函數(shù)放到了PE頭部的導(dǎo)入表中,調(diào)用時(shí)就不需要LoadLib,GetProcAddr,直接jmp 到導(dǎo)入表的地址即可(由PE的加載器填入) 這樣就不會(huì)有VB中多余的API操作影響winapi.GetLastError的值了.所以VB又自作主張的去掉了SetXXXerr...這樣線程中就正常了,當(dāng)然(還是不能調(diào)用其它的VB函數(shù)(特別是和對(duì)象有關(guān)的) 這樣一來(lái),每個(gè)需要用的函數(shù)要用TLB聲明一下,相當(dāng)?shù)穆闊?結(jié)果本來(lái)只需要寫(xiě)一行聲明在源碼中,變成了寫(xiě)到TLB的源文件I/ODL中,再用midl編譯,還要再引用,最后才能使用...(這里己經(jīng)講到關(guān)鍵了,就不再?gòu)U話了,不然pjz說(shuō)我充字?jǐn)?shù)騙稿費(fèi)就不好了-_-!) 總之用TLB寫(xiě)VB函數(shù)不是給VB的程序員用的,是給VC+SDK這類程序員用... 例子:頂樓的聲明去掉,改為TLB即成. 2.不需要處理tls(很多都是暴力copy,不知道有沒(méi)有后遺癥?) 不知道是誰(shuí)發(fā)明的...好像是CSDN的超級(jí)綠豆?這種我看著暈,所以沒(méi)測(cè)試... 例子:http://www.vbgood.com/viewthread.php?tid=88445 (VBProFan 注:iceboy 的 copy tls) 3.不需要編譯成activx exe(這東東會(huì)在注冊(cè)表留下垃圾項(xiàng),從VB的引用中會(huì)看到), 這個(gè)我最早在國(guó)外發(fā)現(xiàn)... 由于和揭密無(wú)關(guān),就不說(shuō)了,簡(jiǎn)單說(shuō)下,如果想取消注冊(cè)表的項(xiàng),可以 shell "filename.exe /unregserver" 例子: http://www.vbgood.com/viewthread.php?tid=65375 4.不需要編譯成p-code(P代碼的壞處眾所周知了) 和揭密無(wú)關(guān),為節(jié)省版面略之...(猜想由于PCODE在虛擬機(jī)中運(yùn)行,所以VB的對(duì)象都是OK的,不會(huì)有什么大問(wèn)題) 例子: 頂樓的那個(gè)國(guó)外的鏈接 5.不需要干掉 setSysXXXerr 頭痛醫(yī)頭,腳頭醫(yī)腳的辦法. nop掉后也只能用VB內(nèi)聲明的API,還是無(wú)法用VB字符串之類的函數(shù) 6.不需要遠(yuǎn)程創(chuàng)建線程... 和揭密無(wú)關(guān),略過(guò) 例子自己找吧: 好像是chenhui530的RtlCreateUserThread 最最關(guān)鍵來(lái)源于這里: http://www.vbgood.com/viewthread.php?tid=88445 這段文字... 需要說(shuō)明的是在線程函數(shù)里面,只有一次調(diào)用API的機(jī)會(huì)~ 也就是說(shuō)我們只有一次機(jī)會(huì)... -_-! 于是開(kāi)始老漢猜想(不是哥德巴赫猜想) 1.那么最好的辦法是什么? 2.為什么在VB的IDE中可以運(yùn)行? 原因只有一點(diǎn):就是VB中己經(jīng)初始化了他需要的對(duì)象. 那么有沒(méi)有初始化對(duì)象的這個(gè)未公開(kāi)的函數(shù)呢? 于是開(kāi)始追蹤: (過(guò)程可到看雪參觀: http://bbs.pediy.com/showthread.php?threadid=36400) 僅貼關(guān)鍵思路點(diǎn):
此時(shí)線程中的第二條API應(yīng)該就是__vbaSetSystemError,也就是非TLB多線程的瓶頸, 這個(gè)時(shí)候己經(jīng)沒(méi)關(guān)系了,因?yàn)樯厦婕航?jīng)完成了初始化.至此揭密己經(jīng)告一段落.為什么參數(shù)是0,4,0? 這個(gè)就不太清楚了,因?yàn)槭菬o(wú)文檔的東東...留給大家繼續(xù)發(fā)現(xiàn)... ------------------------揭密完成----------------------- |
聯(lián)系客服