如題: 我有一些標準dll檔案,,想在vb6 中動態載入,并取得正確回傳值,并進行處理。
在網上找到了一個可以回傳字串的方法,但回傳的是亂碼,用 CopyMemory 進行了轉換,但總崩潰,不知道原因何在,所以,請各位大哥、大嫂、大神們給指點指點,謝謝。
QQ: 2574155801
我不知道怎么上傳附件。可以加我Q給你傳一下。謝了各位大神。
頭一次發貼,就沒看 見在哪設定分數,如果問題解決了,我會多加些分數的。
uj5u.com熱心網友回復:
亂碼,應該是編碼問題。CopyMemory()后程式崩潰,是你未能正確應用這個API(主要是引數傳遞不對)。
uj5u.com熱心網友回復:
Option Explicit
'呼叫 標準 DLL 中函式,并回傳值給呼叫者
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (ByVal dest As Any, ByVal numbytes As Long)
'功能:動態呼叫 標準 DLL 中函式,并取得回傳值
'引數:
' strPluginPathFileName: DLL 檔案路徑
' strFunctionName: DLL 中被呼叫函式名稱
' strArg1~strArg5: DLL 中被呼叫函式的引數(此例子全為字串型別)
'回傳:字串 (回傳 標準 DLL 中函式的回傳值)
Public Function GetPluginInfo(ByVal strPluginPathFileName As String, ByVal strFunctionName As String, Optional ByRef strArg1 As String = "", Optional ByRef strArg2 As String = "", Optional ByRef strArg3 As String = "", Optional ByRef strArg4 As String = "", Optional ByRef strArg5 As String = "") As String
Dim hModule As Long '模塊句柄
Dim pFunction As Long '函式地址
Dim pContent As Long '插件回傳內容指標
Dim tmpContent As String '臨時存放取得的內容
' On Error Resume Next
hModule = LoadLibrary(strPluginPathFileName)
pFunction = GetProcAddress(hModule, strFunctionName)
Dim tmpinfo As New FunctionPtr
Dim tmpFunction As Object
If strArg1 = "" And strArg2 = "" And strArg3 = "" And strArg4 = "" And strArg5 = "" Then
Set tmpFunction = tmpinfo.Create(pFunction, vbString)
CopyMemory tmpContent, StrPtr(tmpFunction.Invoke()), 4
Else
Set tmpFunction = tmpinfo.Create(pFunction, vbString, vbString, vbString, vbString, vbString, vbString)
CopyMemory tmpContent, StrPtr(tmpFunction.Invoke(strArg1, strArg2, strArg3, strArg4, strArg5)), 4
Debug.Print tmpContent
End If
FreeLibrary hModule
GetPluginInfo = tmpContent
Set tmpinfo = Nothing
Set tmpFunction = Nothing
End Function
uj5u.com熱心網友回復:
但是,,就是不知道如何進行 轉換,看了 <<在VB6中用CopyMemory拷貝字串的種種貓膩>> 按照這個也使用了,但就是不成,不知道問題所在。uj5u.com熱心網友回復:
還有就是回傳的這個亂碼,不能直接進行賦值給string變數(提示溢位),也不能用strconv進行轉換(也提示溢位)uj5u.com熱心網友回復:
我用的是手機,看代碼不方便,更無法測驗你的代碼了。你還說你看了“貓膩”的呢,明顯沒看懂!
按你的 CopyMemory 函式宣告,用它拷字串,必須是:
CopyMemory byval strptr(DD), byval strptr(SS), 位元組數
DD是VB6中的String型別變數,在 CopyMemory之前還必須按“位元組數”先賦值足夠長度的值(一般用string()或space()產生)。
已經有足夠長度的值時可以不處理(看需求)。
如果SS是在API函式中反回的值,它多半是ANSI編碼的。
這時還要再用Strconv()把它轉換一下來賦值給別的變數,或輸出。
不轉換必為亂碼。
你說 Strconv()時還“溢位”,
我只能說,兄弟,你撞鬼了……
uj5u.com熱心網友回復:
字串長度確定不了,有長有短而且你的 CopyMemory byval strptr(DD), byval strptr(SS), 位元組數 我也試了,不成,兄弟。
uj5u.com熱心網友回復:
就是按照 貓膩 的方法和他的一模一樣 可他的行,我的不行,唯一不同的地方就是我的字串是dll回傳的亂碼,他的是自己輸入的文本。下面是測驗代碼鏈接,謝謝懂的朋友看看。
http://yunpan.cn/QiiCMEuEwLM6J 訪問密碼 132b
uj5u.com熱心網友回復:
只有算術運算結果才會“溢位”,字串處理,哪來溢位的道理!
最多會提示“記憶體不足”(或類似這個意思的)、非法操作 之類的問題。
uj5u.com熱心網友回復:
對了,我呼叫的是 易語言寫的dll ,他回傳的是文本型,他不是象易語言那個”取拼音.dll“一樣把回傳字串寫入記憶體,然后在vb中呼叫是沒有問題的
uj5u.com熱心網友回復:
字串長度怎么可能“定不了”?你用copymemory,第三個引數難道你會不傳?
它的值是位元組數,你按它的值來作為“字串長度”,分配出來的空間絕對不會少!
你的問題我也不想多說了,就看你能否真正理解。
uj5u.com熱心網友回復:
不好意思,本來想抓個圖給你看一下,,結果現在不出溢位錯誤,而 strconv 也是直接就掛掉了。但是之前一直提示 確定是 溢位 的錯誤。
uj5u.com熱心網友回復:
傳啊,,long 和 string 不都是 4個位元組嗎,,我就直接傳 4 個位元組,,但多于4個位元組程式也是直接 掛掉uj5u.com熱心網友回復:
是啊,我也按 回傳字串的長度來試驗,但都是直接掛掉,不知道是怎么回事,,len 和 lenb 也都試過,都掛掉,哎~~~ 沒辦法了就只能換方法了。uj5u.com熱心網友回復:
很少有人用VB了啊uj5u.com熱心網友回復:
嗯,用人少了,但還有人在用。找了個人看了一下,說在他哪運行沒有問題,也不崩潰,真奇怪,但我用就是不行
。
uj5u.com熱心網友回復:
提示的就是 記憶體溢位 或 是 字串空間溢位, 那就太長了撒,,但回傳的也沒多長啊問題是。uj5u.com熱心網友回復:


直接賦值 或 轉換 就是這錯誤
uj5u.com熱心網友回復:
從你12樓看出:你根本還沒有明白字串是怎么回事。你在6樓說“試了,不成”,我只能懷疑你未能正確應用Copymemory()。
你之前一直在說“溢位”,而最終證明是記憶體溢位。
你要注意“溢位”,跟“記憶體溢位”是完全不同的概念!
你的圖片,我看到了。
如果正如你圖中那點代碼,出現“記憶體溢位”了,
只能說明你的Invoke()函式有問題!!!
Strconv()是內置函式,難道你不懷疑自己的函式,
反而懷疑它來了?!
如果它有問題,別人早發現了,還輪得到你來發現啊!
你在16樓說了“ 回傳的也沒多長啊 ”,你也明白記憶體溢位是“太長了”,
為什么不在aaa=.....Invoke()之后,來句:
msgbox “字串長度:” & len(aaa)
看看它到底是如你想的那樣“沒多長”,還是“非常之長”???
雖然沒看到你的代碼,但我可以肯定:
你未能正確應用copymemory(),
你的Invoke()函式肯定有嚴重錯誤!
uj5u.com熱心網友回復:
你7樓發出來的鏈接,我中午和則才都試過,都是說失效了。
應該說不是我手機的問題吧。
你在7樓說“ 方法和他的一模一樣 ”,
對于你,我只能說:無代碼,無真相!
uj5u.com熱心網友回復:
原來是slowgrace寫的貓膩,很久沒見她和清零來VB版了uj5u.com熱心網友回復:
真的啊?
發個鏈接,我看看她怎么寫的。

她倆是很久沒來過了。
uj5u.com熱心網友回復:
不要做A語言代碼修改為B語言代碼的無用功。也不要做用A語言代碼直接呼叫B語言代碼庫這樣復雜、這樣容易出錯的傻事。
只需讓A、B語言代碼的輸入輸出重定向到文本檔案,或修改A、B語言代碼讓其通過文本檔案輸入輸出。
即可很方便地讓A、B兩種語言之間協調作業。
比如:
A將請求資料寫到檔案a.txt,寫完后改名為aa.txt
B發現aa.txt存在時,讀取其內容,呼叫相應功能,將結果寫到檔案b.txt,寫完后洗掉aa.txt,改名為bb.txt
A發現bb.txt存在時,讀取其內容,讀完后洗掉bb.txt
以上A可以替換為任何一種開發語言或開發環境,B可以替換為任何一種與A不同的開發語言或開發環境。
除非A或B不支持判斷檔案是否存在、檔案讀寫和檔案更名。
但是誰又能舉出不支持判斷檔案是否存在、檔案讀寫和檔案更名的開發語言或開發環境呢?
uj5u.com熱心網友回復:
你不覺得:你這種回復讓人很惡心啊?????
uj5u.com熱心網友回復:
你不覺得,這個回復可以解決所有跨開發環境問題嗎?
uj5u.com熱心網友回復:
即使是“跨開發環境”,要完成資料的“交換/傳送”,也沒必要借助于磁盤檔案。1.通過外設來處理,嚴重影響程式運行速度。
你這種能借助磁盤檔案能完成的,都可以通過記憶體資料完成。(極大量的資料除外,這種情況一般只有在下載檔案時才出現)
2. 使用到的dll,一般都是第三方的dll。其“資料傳送方法”都是確定了的(基本上都是通過記憶體),你不可能讓別人重新發布一個用磁盤檔案交換資料的吧!
3. 如果dll是“自己的”,那多數時候都不存在“跨開發環境”
uj5u.com熱心網友回復:
即使是“跨開發環境”,要完成資料的“交換/傳送”,也沒必要借助于磁盤檔案。1.通過外設來處理,嚴重影響程式運行速度。
你這種能借助磁盤檔案能完成的,都可以通過記憶體資料完成。(極大量的資料除外,這種情況一般只有在下載檔案時才出現)
2. 使用到的dll,一般都是第三方的dll。其“資料傳送方法”都是確定了的(基本上都是通過記憶體),你不可能讓別人重新發布一個用磁盤檔案交換資料的吧!
3. 如果dll是“自己的”,那多數時候都不存在“跨開發環境”
uj5u.com熱心網友回復:
即使是“跨開發環境”,要完成資料的“交換/傳送”,也沒必要借助于磁盤檔案。1.通過外設來處理,嚴重影響程式運行速度。
你這種能借助磁盤檔案能完成的,都可以通過記憶體資料完成。(極大量的資料除外,這種情況一般只有在下載檔案時才出現)
2. 使用到的dll,一般都是第三方的dll。其“資料傳送方法”都是確定了的(基本上都是通過記憶體),你不可能讓別人重新發布一個用磁盤檔案交換資料的吧!
3. 如果dll是“自己的”,那多數時候都不存在“跨開發環境”、“A語言B語言”的問題了,甚至DLL都用不著了,全部代碼整合在一個專案中。這時更用不著“磁盤檔案來交換資料”。
假設一個如下的應用場景,恐怕“磁盤交換”就很不合理:
某專家研究了一個演算法(DLL發布),可用于股票(或外匯)分析,指導投資者的交易和決策,當然這個“指導”還是“僅供參考”。要求輸入“實時行情變化資料”(可能有幾百個,也可能有幾萬甚至更多,函式介面有另一個引數指示資料量)、輸出圖表的HWND(當然這個是Form的,還是PictureBox的,決定于呼叫者),投資者通過“觀看”這個圖表(比如類似燭狀圖、K線圖)的變化,決定自己的股票或外匯的買賣交易。
“實時行情資料”肯定是自己的程式負責采集、記錄(具體是通過Web,還是交易平臺提供資料通訊,這兒不用管),比如2秒采集一次,或是5秒采集一次。隨著時間推移,資料量肯定逐漸增加(程式中有必要時,可以限制最大資料量),積累一定量的資料后,就可呼叫DLL中的函式進行分析,分析結果以圖表模式繪制到指定的物件(hWnd標識)中。
你想想,這個“資料交換程序”,如果通過磁盤檔案來做:
呼叫者把大量的資料寫進磁盤……
被呼叫的程序又去從磁盤讀資料……
分析結果,生成圖片檔案,寫進磁盤……
讀圖片檔案,把影像繪制出來……
如此反復~~~(因為肯定不是只分析一次,而是不停的采集、接著又來一輪分析)
你不覺得很別扭、運行效率很低嗎????
uj5u.com熱心網友回復:
不要低估作業系統檔案處理的智商。誰說檔案一定要保存在磁盤上?保存在RamDisk上不行嗎?
誰說檔案一定保存在本地?映射網路驅動器不行嗎?
無profiler不要談效率!!尤其在這個云計算、虛擬機、模擬器、CUDA、多核 、多級cache、指令流水線、多種存盤介質、……滿天飛的時代!
uj5u.com熱心網友回復:
所謂的動態呼叫API有什么意義。。。。轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/120584.html
標籤:VB基礎類
