[英]VB6 - Declaring and calling C DLL with pointers
I have an old C DLL I use to call from Ruby, but now I need to call it from VB6 and I can't figure out the correct way to do so.
这是我需要的 function 的 header:
int Decrunch(const BYTE *src, BYTE *dest, DWORD src_length)
*src 是一个字节序列,将被 function 解密
*dest 是一个缓冲区,它将接收解密的数据。 我可以使用 dest=NULL 调用 function,它将返回解密数据的大小,因此我可以使用它来创建具有正确大小的缓冲区。
我尝试将 src 和 dest 都声明为字符串(就像我在 Ruby 中所做的那样),但它不起作用。 我还尝试将它们声明为 Byte 并传递字节数组的第一个元素,正如一些教程所指出的那样,但我认为我没有正确地做到这一点。
有人可以帮我弄这个吗?
谢谢!
航空代码
Private Declare DecrunchGetLength Alias "Decrunch" Lib "somedll.DLL" (ByRef src As Byte, ByVal nullptr As Long, ByVal SrcLength As Long) As Long
Private Declare Decrunch Alias "Decrunch" Lib "somedll.DLL" (ByRef src As Byte, ByRef dest As Byte, ByVal SrcLength As Long) As Long
Dim destLen As Long
Dim src(0 To 9) As Byte
Dim dest() As Byte
' get bytes into src somehow
' get dest length
destLen = DecrunchGetLen( src(0), 0, 10)
ReDim dest(0 To destLen - 1)
destLen = Decrunch( src(0), dest(0), 10)
有用的链接
您可以像这样使用CDECL调用thunk
Option Explicit
'--- for VirtualProtect'
Private Const PAGE_EXECUTE_READWRITE As Long = &H40
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) 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 CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const STR_MYDLL As String = "my.dll"
Private Type UcsParamThunk
pfn As Long
Call_(0 To 7) As Long
End Type
Private m_hModule As Long
Private m_uCallThunk As UcsParamThunk
Private Sub Form_Load()
Dim baSrc() As Byte
Dim baDst() As Byte
On Error GoTo EH
ReDim baSrc(0 To 10000) As Byte
ReDim baDst(0 To 20000) As Byte
pvCallFunc "Decrunch", VarPtr(baSrc(0)), VarPtr(baDst(0)), UBound(baSrc) + 1
Exit Sub
EH:
MsgBox Error$, vbCritical
End Sub
Private Function pvCallFunc(sFunc As String, ParamArray A()) As Long
Dim pfn As Long
Dim lIdx As Long
Dim aParams() As Long
If m_hModule = 0 Then
m_hModule = LoadLibrary(STR_MYDLL)
If m_hModule = 0 Then
Err.Raise vbObjectError, , STR_MYDLL & " not found"
End If
pvInitCallCdeclThunk m_uCallThunk
End If
pfn = GetProcAddress(m_hModule, sFunc)
If pfn = 0 Then
Err.Raise vbObjectError, , "Export not found: " & sFunc
End If
ReDim aParams(0 To UBound(A) + 1) As Long
For lIdx = 0 To UBound(A)
aParams(lIdx) = CLng(A(lIdx))
Next
pvCallFunc = CallWindowProc(m_uCallThunk.pfn, pfn, UBound(aParams), VarPtr(aParams(0)), 0)
End Function
Private Sub pvInitCallCdeclThunk(Thunk As UcsParamThunk)
'void _stdcall thunk(int pfn, int count, int args, int dummy)
' push ebp
' mov ebp, esp
' mov ecx, count
' jecxz _skip_params
' mov edx, args
'_params_loop:
' push dword ptr [edx + ecx * 4 - 4]
' loop _params_loop
'_skip_params:
' call pfn
' mov esp,ebp
' pop ebp
' ret 10h
' nop
' nop
With Thunk
.Call_(0) = &H8BEC8B55
.Call_(1) = &H9E30C4D
.Call_(2) = &HFF10558B
.Call_(3) = &HE2FC8A74
.Call_(4) = &H855FFFA
.Call_(5) = &HC25DE58B
.Call_(6) = &H90900010
.pfn = VarPtr(.Call_(0))
Call VirtualProtect(Thunk, Len(Thunk), PAGE_EXECUTE_READWRITE, 0)
End With
End Sub
如果您遇到来自其他语言(例如 C++)的指针,作为一个好的一般经验法则,您应该在 VB6 中将它们声明为“Any”:
Private Declare Decrunch Alias "Decrunch" Lib "somedll.DLL" (cpbSrc As Any, pbDest As Any, dwDataLength As Long) As Long
Dim cpbSrc(0 to 10) as byte, pbDest() as byte, dwDataLength as long
Call Decrunch(cpbSrc(0), Byval 0, dwDataLength) ' Pass NULL pointer to return the length
Redim pbDest(0 to dwDataLength - 1) ' initialize the pbDest array
Debug.Print Decrunch(cpbSrc(0), pbDest(0), dwDataLength)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.