Private Declare Function get_cre_str Lib "CreDLL.dll" (pBuffer As Byte, pStr As Byte) As Integer
' 如果除錯運行提示“找不到DLL檔案”,你把CreDLL.dll加上完整路徑試試。
' 編譯 exe時要把路徑去掉,只留 "CreDLL.dll"
Private Sub Command1_Click()
Dim arrIN() As Byte
Dim arrOut() As Byte
ReDim arrOut(39&)
arrIN = StrConv("123456789", vbFromUnicode)
If (0 = get_cre_str(arrIN(0), arrOut(0))) Then
MsgBox "呼叫處理失敗。", 64
Else
MsgBox "處理結果:" & Left$(StrConv(arrOut, vbUnicode), 35), 64
End If
End Sub
Imports System
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Public Class LibWrap
' Visual Basic does not support varargs, so all arguments must be
' explicitly defined. CallingConvention.Cdecl must be used since the stack
' is cleaned up by the caller.
' int printf( const char *format [, argument]... )
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, d As Double) As Integer
End Function
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, s As String) As Integer
End Function
End Class 'LibWrap
Public Class App
Public Shared Sub Main()
LibWrap.printf(ControlChars.CrLf + "Print params: %i %f", 99,
99.99)
LibWrap.printf(ControlChars.CrLf + "Print params: %i %s", 99, _
"abcd")
End Sub 'Main
End Class 'App
不過,要我來做,我會再寫一個 VC++ DLL,用__stdcall 函式將原來的函式封一層。
uj5u.com熱心網友回復:
你這是VB.NET,不是VB6吧!
uj5u.com熱心網友回復:
好多時候,是廠家規定了情況,你按他的要求去處理,是被限定的,沒辦法,總得生活嘛,好在有解決方案
樓主看來不是真正的VB老人,要分清VB6和.NET再發貼
uj5u.com熱心網友回復:
將A替換為VB6,B替換為呼叫你這個DLL的VC
uj5u.com熱心網友回復:
是 VB6,微軟網站提供的例子。只不過子類這種手段我們很少用。
uj5u.com熱心網友回復:
VB 不能以常規方式呼叫 CDECL 約定函式,但可以用子類方式訪問。下面是一個例子:
Imports System
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Public Class LibWrap
' Visual Basic does not support varargs, so all arguments must be
' explicitly defined. CallingConvention.Cdecl must be used since the stack
' is cleaned up by the caller.
' int printf( const char *format [, argument]... )
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, d As Double) As Integer
End Function
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, s As String) As Integer
End Function
End Class 'LibWrap
Public Class App
Public Shared Sub Main()
LibWrap.printf(ControlChars.CrLf + "Print params: %i %f", 99,
99.99)
LibWrap.printf(ControlChars.CrLf + "Print params: %i %s", 99, _
"abcd")
End Sub 'Main
End Class 'App
Imports System
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Public Class LibWrap
' Visual Basic does not support varargs, so all arguments must be
' explicitly defined. CallingConvention.Cdecl must be used since the stack
' is cleaned up by the caller.
' int printf( const char *format [, argument]... )
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, d As Double) As Integer
End Function
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, s As String) As Integer
End Function
End Class 'LibWrap
Public Class App
Public Shared Sub Main()
LibWrap.printf(ControlChars.CrLf + "Print params: %i %f", 99,
99.99)
LibWrap.printf(ControlChars.CrLf + "Print params: %i %s", 99, _
"abcd")
End Sub 'Main
End Class 'App
Imports System
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Public Class LibWrap
' Visual Basic does not support varargs, so all arguments must be
' explicitly defined. CallingConvention.Cdecl must be used since the stack
' is cleaned up by the caller.
' int printf( const char *format [, argument]... )
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, d As Double) As Integer
End Function
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, s As String) As Integer
End Function
End Class 'LibWrap
Public Class App
Public Shared Sub Main()
LibWrap.printf(ControlChars.CrLf + "Print params: %i %f", 99,
99.99)
LibWrap.printf(ControlChars.CrLf + "Print params: %i %s", 99, _
"abcd")
End Sub 'Main
End Class 'App
Imports System
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Public Class LibWrap
' Visual Basic does not support varargs, so all arguments must be
' explicitly defined. CallingConvention.Cdecl must be used since the stack
' is cleaned up by the caller.
' int printf( const char *format [, argument]... )
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, d As Double) As Integer
End Function
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
format As String, i As Integer, s As String) As Integer
End Function
End Class 'LibWrap
Public Class App
Public Shared Sub Main()
LibWrap.printf(ControlChars.CrLf + "Print params: %i %f", 99,
99.99)
LibWrap.printf(ControlChars.CrLf + "Print params: %i %s", 99, _
"abcd")
End Sub 'Main
End Class 'App
' 這個 API是 CDecl呼叫約定的,IDE下會報運行錯;
' 但在編譯成exe(本機代碼)執行完全正常。
'
Private Declare Function get_ewm_str Lib "KeyCreatDLL.dll" ( _
lpInBuffer As Byte, lpOutBuff As Byte) As Byte
Private Sub TestCDeclCall()
Const TEXT_TAB = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
Dim arrIn() As Byte
Dim arrOut() As Byte
Dim strTemp As String
Dim i As Integer
strTemp = ""
Call Randomize
For i = 1 To 20 ' 隨機選取 20個字符
strTemp = strTemp & Mid$(TEXT_TAB, 1& + CLng(35& * Rnd()), 1&)
Next
' 準備“輸入資料”
arrIn = StrConv(strTemp & vbNullChar, vbFromUnicode)
' 準備“輸出緩沖區”
ReDim arrOut(35&)
Me.Cls
Me.Print "測驗字串: " & strTemp ' 隨機組合的輸入測驗串
' 在IDE下運行,下面這句會報運行錯誤: “DLL 呼叫約定錯誤”
' 在訊息框中點“除錯”,然后把執行游標拖到“輸出結果”那兒繼續執行就行。
i = get_ewm_str(arrIn(0&), arrOut(0&))
' 在IDE下運行,這兒的i沒有得到回傳值。但編譯后可以正確得到回傳值。
If (0 = i) Then
Me.Print "函式執行失敗。"
Else
Me.Print "函式回傳值: " & i
' ***** 在IDE下運行,前面API呼叫報錯后,從下面這句繼續執行
Me.Print "處理后結果: " & StrConv(arrOut, vbUnicode)
End If
End Sub
Private Sub Command1_Click()
Call TestCDeclCall
End Sub
VB6 宣告代碼:
Declare Function get_cre_str Lib "CreDLL.dll" (ByVal buffer As String, ByVal pstr As String) As Byte
VB6 呼叫代碼:
Dim buffer As String
Dim pstr As String
buffer = "123"
pstr = Space$(64) '在 VB6 里給 get_cre_str 的第二個引數(輸出引數)分配記憶體
Dim bOK As Byte
bOK = get_cre_str(buffer, pstr)
'pstr 里查找 \0,并舍棄其后的字符
Dim n As Integer
n = InStr(1, pstr, Chr$(0))
If n >= 1 Then
pstr = Left$(pstr, n - 1)
End If
uj5u.com熱心網友回復:
重點是:第二個引數(輸出引數)應該由 VB6 分配好記憶體。示例代碼如下:
VB6 宣告代碼:
Declare Function get_cre_str Lib "CreDLL.dll" (ByVal buffer As String, ByVal pstr As String) As Byte
VB6 呼叫代碼:
Dim buffer As String
Dim pstr As String
buffer = "123"
pstr = Space$(64) '在 VB6 里給 get_cre_str 的第二個引數(輸出引數)分配記憶體
Dim bOK As Byte
bOK = get_cre_str(buffer, pstr)
'pstr 里查找 \0,并舍棄其后的字符
Dim n As Integer
n = InStr(1, pstr, Chr$(0))
If n >= 1 Then
pstr = Left$(pstr, n - 1)
End If
這個根本不是“重點”好不!
你看看我在12樓的回復。
我在2樓給樓主回復的示例代碼,那也是“在VB6中分配好輸出記憶體”的了。
并且,他的這個API的“輸出字串”是ANSI格式的編碼。
在你的這段代碼中,你用:
pstr = Left$(pstr, n - 1)
根本不能把“NULL”字符去除干凈!