-
how to Fast Call cdecl api like sqlite3.dll?
With m_cCDECL
sqlite3_exec = .CallFunc("sqlite3_exec", sqlite3, VarPtr(bvData(0)), 0, 0, 0)
End With
I WANT TO DO LIKE THIS:
address1=GetProADDRESS (dll,"sqlite3_exec")
bind_dllto_address(address1,addressof Mysqlite3_exec)
function Mysqlite3_exec(ByVal sqlite3 As Long, ByVal zSql As long)
'ASMCODE:
'CALL address1(sqlite3 ,zSql )
'clear something?
end function
this code maybe to slowly!
Code:
Public Function sqlite3_exec(ByVal sqlite3 As Long, ByVal zSql As String) As Long
'int sqlite3_exec(
' sqlite3*, /* An open database */
' const char *sql, /* SQL to be evaluated */
' int (*callback)(void*,int,char**,char**), /* Callback function */
' void *, /* 1st argument to callback */
' char **errmsg /* Error msg written here */
');
Dim bvData() As Byte
Dim lSize As Long
Dim lRet As Long
If LenB(zSql) Then
lSize = Len(zSql) * 4
ReDim bvData(lSize)
lRet = WideCharToMultiByte(CP_UTF8, 0, StrPtr(zSql), Len(zSql), bvData(0), lSize + 1, vbNullString, 0)
If lRet Then
ReDim Preserve bvData(lRet - 1)
End If
End If
If m_bLoaded Then
With m_cCDECL
sqlite3_exec = .CallFunc("sqlite3_exec", sqlite3, VarPtr(bvData(0)), 0, 0, 0)
End With
Else
sqlite3_exec = SQLITE_ERROR
End If
End Function
-
Re: hao to call Sqlite3.dll with cdecl?
HOW TO WRITE ASM CODE "PutAsmToMyFunctionAdress",BY writeProcessmemory
ALSO CAN USE CdeclCallA:
BUT I WANT TO Make a Function ,and Put Some asmcode,then
no need for next
Code:
address1=GetProADDRESS (dll,"sqlite3_exec")
PutAsmToMyFunctionAdress(addressof Mysqlite3_exec , address1 , argCount=2)
function Mysqlite3_exec(ByVal sqlite3 As Long, ByVal zSql As long)
msgbox "asm code here"
end function
sub PutAsmToMyFunctionAdress(VBFunctionAddress,DllAddress,ArgCount)
'writeProcessmemory -1, VBFunctionAddress,ASM CODE
end sub
function Mysqlite3_exec(ByVal sqlite3 As Long, ByVal zSql As long)
'ASMCODE:
'CALL address1(sqlite3 ,zSql )
'clear something?
end function
dim i as long
for i=1 to 10000
Mysqlite3_exec(**,**)
next
Code:
Public Function CdeclCallA(sDll As String, sFunc As String, ByVal RetType As VbVarType, ParamArray P() As Variant)
Dim i As Long, pFunc As Long, V(), HRes As Long
V = P 'make a copy of the params, to prevent problems with VT_Byref-Members in the ParamArray
For i = 0 To UBound(V)
If VarType(P(i)) = vbString Then P(i) = StrConv(P(i), vbFromUnicode): V(i) = StrPtr(P(i))
VType(i) = VarType(V(i))
VPtr(i) = VarPtr(V(i))
Next i
HRes = DispCallFunc(0, GetFuncPtr(sDll, sFunc), CC_CDECL, RetType, i, VType(0), VPtr(0), CdeclCallA)
For i = 0 To UBound(P) 'back-conversion of the ANSI-String-Results
If VarType(P(i)) = vbString Then P(i) = StrConv(P(i), vbUnicode)
Next i
If HRes Then Err.Raise HRes
End Function
-
Re: hao to call Sqlite3.dll with cdecl?
The fastest approach for VB6 is to compile the sqlite 3 library with __stdcall instead of __cdecl.
-
Re: hao to call Sqlite3.dll with cdecl?
Coders Corner - VB6 CDECL
http://sandsprite.com/blogs/index.php?uid=11&pid=410
http://sandsprite.com/CodeStuff/vb_cdecl.zip
IT'S change VB Function To Cdecl,but i want to Call Vb Function Like Call Cdecl
i want to call VB_Stdcall_Sum(11,22),it will call cdecl: test.dll sum(11,22)
result=33
what Code is For Build_CDecl_InVbStdcallFunction?
Code:
Function VB_Stdcall_Sum(ByVal x As Long,byval y as long ) As Long
msgbox "Put AsmCode"
end Function
Function MyVB_Stdcall_CallBack(ByVal x As Long) As Long
MsgBox "In VB call back! x=" & x
MyVB_Stdcall_CallBack = x + 1
End Function
Function VB_CallBack2(ByVal x As Long, ByVal y As Long) As Long
MsgBox "In VB_CallBack2 x=" & x & " y=" & y
VB_CallBack2 = x - y
End Function
Build_CDecl_CallBack_Wrapper AddressOf VB_CallBack2, 2
lpfnCallback2 = GetProcAddress(h, "CallBack2")
ret = CallCdecl(lpfnCallback2, VarPtr(cdeclCallBackStub(0)), 2, 1)
MsgBox "Callback2 Worked, results 2-1 = " & ret
-
Re: hao to call Sqlite3.dll with cdecl?
i want a way for call cdecl like call vb function,no need call api,no need DispCallFunc ,no need CallWindowProcA
DispCallFunc 0, FuncAddr, 1, ReturnType, ParamCount, ParamTypes(0), ParamPtrs(0), CallCDECL
VB_Stdcall_Sum=call test.dll cdecl function:sum
Code:
testaddress=getprocess("sum") ' cdecl function from test.dll
Build_CDecl_InVbStdcallFunction (testaddress,addressof VB_Stdcall_Sum,args=2)
dim a as long,b as long ,c as long
a=11
b=22
c=VB_Stdcall_Sum(a,b)
msgbox c=33
Function VB_Stdcall_Sum(ByVal x As Long,byval y as long ) As Long
msgbox "Put AsmCode"
end Function
-
Re: hao to call Sqlite3.dll with cdecl?
some dll is __cdecl,and we have no source code,so only find a way call quickly
why wen call cdecl function,exe cash?
Code:
Public Sub MakeFunctionCdecl_C(DllFunAddr As Long, BackFunAddr As Long, Args As Long)
'
Dim Code() As Byte, JmpBackAddr As Long
Dim OldProtect As Long
Dim ByteLen As Long
ByteLen = 5 + Args
ReDim Code(ByteLen)
Vblegend.VirtualProtect ByVal DllFunAddr, ByteLen, 64, OldProtect
JmpBackAddr = DllFunAddr - BackFunAddr - 5
Code(0) = &HE9
Vblegend.CopyMemory Code(1), JmpBackAddr, 4
Dim i As Long
For i = 1 To Args
Code(5 + i) = &H59 'pop ecx'恢复堆栈
Next
Vblegend.WriteProcessMemory -1, ByVal BackFunAddr, Code(0), ByteLen, 0
End Sub
-
Re: hao to call Sqlite3.dll with cdecl?
You can call __cdecl functions directly in the compiled state if you declare __cdecl functions in a tlb without any tricks.
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
The trick
You can call __cdecl functions directly in the compiled state if you declare __cdecl functions in a tlb without any tricks.
IF IT'S NOT CALL api from sqlit3.dll,how to do?
i put sqlit3.dll in 001.res,load res in memory,and call from Memory ADDRESS.
HOW TO CALL CDECL API (address ) by asm?
Code:
Declare Function LoadLibrary Lib "kernel32.dll" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Declare Function FreeLibrary Lib "kernel32.dll" (ByVal hLibModule As Long) As Long
Declare Function GetProcAddress Lib "kernel32.dll" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Declare Function DispCallFunc Lib "oleaut32.dll" (ByVal pvInstance As Long, ByVal offsetinVft As Long, ByVal CALLCONV As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByVal paTypes As Long, ByVal paValues As Long, ByRef retVAR As Variant) As Long
Private Sub CallCDeclAPI()
Dim fPtr As Long, hMod As Long
Dim vParamType As Integer, vRtn As Variant, vParams As Variant
Const CC_CDECL As Long = 1
hMod = LoadLibrary("MyDLL.dll")
If hMod Then
fPtr = GetProcAddress(hMod, "SetNotificationProc")
If fPtr Then
vParams = pvGetAddrOf(AddressOf NewNotification)
vParamType = vbLong
DispCallFunc 0, fPtr, CC_CDECL, vbEmpty, 1, VarPtr(vParamType), VarPtr(vParams), vRtn
End If
FreeLibrary hMod
End If
End Sub
Sub NewNotification()
'
End Sub
Private Function pvGetAddrOf(inAddr As Long) As Long
pvGetAddrOf = inAddr
End Function
Code:
实用代码:VBAnyCall类——任意调用函数代码(包括__cdecl调用约定的函数及汇编代码)
VB
>
API
收藏
回复
[问题点数:200分,结帖人supergreenbean]
supergreenbean
等级
勋章
Blank
Blank
结帖率 100%
'------------------------------ 类模块 VBAnyCall.cls ------------------------------
Option Explicit
'本模块名称
Private Const THIS_MODULE_NAME As String = "CVBAnyCall"
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 Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
Private mlParameters() As Long '参数列表
Private mlCallAddress As Long '调用的函数地址
Private mbCodeBuffer() As Byte '汇编代码字节
Private mlLastCodePosition As Long '用以跟踪最后添加的字节
Private mbCodeBytes() As Byte '用于存储代码字节
Private mfStdCall As Boolean '是否为__stdcall调用约定 True=__stdcall False=__cdecl
'**************************************************************************
'* 暴露的接口 *
'**************************************************************************
'调用汇编字节字符串方法
'sCodeStr :汇编字节字符串
'FuncParams():参数数组
Public Function CallCodeBytes(ByVal sCodeStr As String, ParamArray FuncParams()) As Long
On Error Resume Next
Dim i As Long
ReDim mlParameters(0)
ReDim mbCodeBuffer(0)
mlCallAddress = 0
mbCodeBytes = ByteCodeStrToBin(sCodeStr)
i = UBound(mbCodeBytes)
If Err.Number <> 0 Then
Call RaiseErr("代码字节字符串转换错误")
Exit Function
End If
mlCallAddress = VarPtr(mbCodeBytes(0))
If mlCallAddress = 0 Then
Call RaiseErr("代码入口点地址错误")
Exit Function
End If
ReDim mlParameters(UBound(FuncParams) + 1)
For i = 1 To UBound(mlParameters)
mlParameters(i) = CLng(FuncParams(i - 1))
Next i
CallCodeBytes = CallWindowProc(PrepareCode, 0, 0, 0, 0)
End Function
'按地址调用代码
'lFuncAddress:函数地址
'FuncParams():参数数组
Public Function CallByAddress(ByVal lFuncAddress As Long, ParamArray FuncParams()) As Long
Dim i As Long
ReDim mlParameters(0)
ReDim mbCodeBuffer(0)
mlCallAddress = 0
mlCallAddress = lFuncAddress
If mlCallAddress = 0 Then
Call RaiseErr("代码入口点地址错误")
Exit Function
End If
ReDim mlParameters(UBound(FuncParams) + 1)
For i = 1 To UBound(mlParameters)
mlParameters(i) = CLng(FuncParams(i - 1))
Next i
CallByAddress = CallWindowProc(PrepareCode, 0, 0, 0, 0)
End Function
'调用DLL函数
'sDllName:Dll名称
'sFuncName:函数的名称
'FuncParams():参数数组
Public Function CallApiByName(ByVal sDllName As String, ByVal sFuncName As String, ParamArray FuncParams()) As Long
Dim hLib As Long, i As Long
ReDim mlParameters(0)
ReDim mbCodeBuffer(0)
mlCallAddress = 0
hLib = LoadLibrary(ByVal sDllName)
If hLib = 0 Then
Call RaiseErr("Dll文件未找到")
Exit Function
End If
mlCallAddress = GetProcAddress(hLib, ByVal sFuncName)
If mlCallAddress = 0 Then
Call RaiseErr("代码入口点地址错误")
FreeLibrary hLib
Exit Function
End If
ReDim mlParameters(UBound(FuncParams) + 1)
For i = 1 To UBound(mlParameters)
mlParameters(i) = CLng(FuncParams(i - 1))
Next i
CallApiByName = CallWindowProc(PrepareCode, 0, 0, 0, 0)
FreeLibrary hLib
End Function
'汇编字节字符串转换为代码字节数组
'sByteCode:汇编字节字符串
Public Function ByteCodeStrToBin(ByVal sByteCode As String) As Byte()
Dim s() As String
Dim b() As Byte
Dim i As Long
s = Split(Trim(sByteCode), " ")
If UBound(s) >= 0 Then
ReDim b(UBound(s))
End If
For i = 0 To UBound(s)
b(i) = CByte("&h" & s(i))
Next
ByteCodeStrToBin = b
End Function
'是否为__stdcall调用约定 True=__stdcall False=__cdecl
Public Property Let IsStandardCall(fVal As Boolean)
mfStdCall = fVal
End Property
Public Property Get IsStandardCall() As Boolean
IsStandardCall = mfStdCall
End Property
'**************************************************************************
'* 暴露的接口 *
'**************************************************************************
'**************************************************************************
'******************************** 私有函数 ********************************
'**************************************************************************
Private Function PrepareCode() As Long
Dim i As Long, lCodeStartPosition As Long
ReDim mbCodeBuffer(18 + 32 + 6 * UBound(mlParameters))
lCodeStartPosition = GetAlignedlCodeStartPosition(VarPtr(mbCodeBuffer(0)))
mlLastCodePosition = lCodeStartPosition - VarPtr(mbCodeBuffer(0))
For i = 0 To mlLastCodePosition - 1
mbCodeBuffer(i) = &HCC
Next
AddByteToCode &H58 'pop eax'将返回地址存入eax
AddByteToCode &H59 'pop ecx' / 去掉
AddByteToCode &H59 'pop ecx'| 事先
AddByteToCode &H59 'pop ecx'| 被压入
AddByteToCode &H59 'pop ecx' \ 的参数
AddByteToCode &H50 'push eax'重新压入返回地址
For i = UBound(mlParameters) To 1 Step -1
AddByteToCode &H68 'push parameter(i)'压入我们的参数
AddLongToCode mlParameters(i)
Next
AddCallToCode mlCallAddress
'VB之所以不能用__cdecl调用约定的函数就是因为VB不会自己恢复堆栈。
If Not mfStdCall Then '如果调用约定不是__stdcall,那就自己恢复堆栈
For i = 1 To UBound(mlParameters)
AddByteToCode &H59 'pop ecx'恢复堆栈
Next
End If
AddByteToCode &HC3
AddByteToCode &HCC
PrepareCode = lCodeStartPosition
End Function
Private Sub AddCallToCode(lAddr As Long)
AddByteToCode &HE8
AddLongToCode lAddr - VarPtr(mbCodeBuffer(mlLastCodePosition)) - 4
End Sub
Private Sub AddLongToCode(lCode As Long)
Dim i As Integer
Dim b(3) As Byte
CopyMemory b(0), lCode, 4
For i = 0 To 3
AddByteToCode b(i)
Next
End Sub
Private Sub AddByteToCode(bCode As Byte)
mbCodeBuffer(mlLastCodePosition) = bCode
mlLastCodePosition = mlLastCodePosition + 1
End Sub
Private Function GetAlignedlCodeStartPosition(lAddr As Long) As Long
GetAlignedlCodeStartPosition = lAddr + (15 - (lAddr - 1) Mod 16)
If (15 - (lAddr - 1) Mod 16) = 0 Then GetAlignedlCodeStartPosition = GetAlignedlCodeStartPosition + 16
End Function
Private Sub RaiseErr(ByVal sErrMsg As String)
Err.Raise vbObjectError + &H1321, "VBAnyCall", sErrMsg
End Sub
Private Sub Class_Initialize()
mfStdCall = True
End Sub
'**************************************************************************
'******************************** 私有函数 ********************************
'**************************************************************************
2004-04-12 00:14:17楼主
supergreenbean
等级
勋章
Blank
Blank
使用例子:
'------------------------------ 窗体模块 Form1.frm ------------------------------
Option Explicit
'本模块名称
Private Const THIS_MODULE_NAME As String = "Form1"
Private goAnyCall As New CVBAnyCall
Private WithEvents cmd As CommandButton
Private WithEvents lst As ListBox
Private Sub Form_Initialize()
'使用SEH,防止程序崩溃
'Call InitExceptionHandler
End Sub
Private Sub Form_Load()
'移动窗体
Me.Height = 5130
Me.Width = 4935
'添加按钮
Set cmd = Me.Controls.Add("VB.CommandButton", "Command1")
With cmd
.Default = True
.Caption = "运行例子"
.Move 1290, 3990, 2235, 405
.Visible = True
End With
'添加列表
Set lst = Me.Controls.Add("VB.ListBox", "List1")
With lst
.Move 120, 120, 4575, 3480
.Visible = True
End With
End Sub
Private Sub cmd_Click()
On Error GoTo Error_Handler
Dim sByteCode As String
Dim bBinCode() As Byte
Dim i As Long
Dim sDll As String
i = 123
sDll = "J:\User-C\CallTest\Debug\CallTest.dll"
'运行汇编语言字节字符串
lst.AddItem "直接运行汇编语言字节字符串,调用约定为__stdcall"
sByteCode = "8B 44 24 04 C2 04 00"
goAnyCall.IsStandardCall = True
lst.AddItem "返回值:" & goAnyCall.CallCodeBytes(sByteCode, 123)
lst.AddItem "直接运行汇编语言字节字符串,调用约定为__cdecl"
sByteCode = "8B 44 24 04 C3"
goAnyCall.IsStandardCall = False
lst.AddItem "返回值:" & goAnyCall.CallCodeBytes(sByteCode, 123)
'按地址运行汇编语言字节
lst.AddItem "按地址运行汇编语言字节,调用约定为__stdcall"
sByteCode = "8B 44 24 04 C2 04 00"
bBinCode = goAnyCall.ByteCodeStrToBin(sByteCode)
goAnyCall.IsStandardCall = True
lst.AddItem "返回值:" & goAnyCall.CallByAddress(VarPtr(bBinCode(0)), 123)
lst.AddItem "按地址运行汇编语言字节,调用约定为__cdecl"
sByteCode = "8B 44 24 04 C3"
bBinCode = goAnyCall.ByteCodeStrToBin(sByteCode)
goAnyCall.IsStandardCall = False
lst.AddItem "返回值:" & goAnyCall.CallByAddress(VarPtr(bBinCode(0)), 123)
'按地址运行VB函数
lst.AddItem "按地址运行VB函数,调用约定为__stdcall"
lst.AddItem "i=" & CStr(i)
goAnyCall.IsStandardCall = True
lst.AddItem "返回值:" & goAnyCall.CallByAddress(AddressOf CallTest, VarPtr(i))
'调用Dll函数
'C函数原型
'int __stdcall CallTestS(int *a){
' int b;
' b=*a;
' *a+=111;
' return b;
'}
lst.AddItem "调用Dll函数,调用约定为__stdcall"
goAnyCall.IsStandardCall = True
lst.AddItem "返回值:" & goAnyCall.CallApiByName(sDll, "CallTestS", VarPtr(i))
lst.AddItem "i=" & CStr(i)
'C函数原型
'int __cdecl CallTestC(int *a){
' int b;
' b=*a;
' *a+=111;
' return b;
'}
lst.AddItem "调用Dll函数,调用约定为__cdecl"
goAnyCall.IsStandardCall = False
lst.AddItem "返回值:" & goAnyCall.CallApiByName(sDll, "CallTestC", VarPtr(i))
lst.AddItem "i=" & CStr(i)
Exit Sub
Error_Handler:
'自定义错误处理
'调用默认错误处理函数
'Call DefaultErrorHandler(THIS_MODULE_NAME)
End Sub
-
Re: hao to call Sqlite3.dll with cdecl?
how to call cdecl_add by function VB_ADD(11,22)?
Code:
function VB_ADD(BYVAL A AS LONG ,byval b as long )
msgbox "writeprocessMemory asm change code here"
end function
CDECL DLL
Code:
int __cdecl cdecl_add(int a, int b)
{
return a + b;
}
int main()
{
int x, y;
x = stdcall_add(0x123, 0x456);
y = cdecl_add(0x123, 0x456);
return 0;
}
ASMCODE:
004010B7 |. 8945 FC mov dword ptr [ebp-0x4], eax
004010BA |. 68 56040000 push 0x456
004010BF |. 68 23010000 push 0x123
004010C4 |. E8 41FFFFFF call 0040100A ; __cdecl
004010C9 |. 83C4 08 add esp, 0x8 ; 由调用者维持堆栈平衡
004010CC |. 8945 F8 mov dword ptr [ebp-0x8], eax
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
xiaoyao
...how to call cdecl_add by function VB_ADD(11,22)?
There is usually no need, to fumble around with ASM-Code (making your whole App a ticking time-bomb).
Especially not in cases, where the (__cdecl-)function you plan to call, has to perform:
- a whole lot of stuff internally (as e.g. the sqlite3_exec(...) function does, with dozens of sub-calls and operations)
You still do not seem to understand, that a function-calls total-timing (until it returns) has two parts:
1.) the call overhead (usually in the range of 1-100 nano-seconds)
2.) the time the function itself needs (to process its "implementation", aka the instructions in its function-body)
And since the above second part is (at least for sqlite3_exec) more in the range of micro-seconds,
it does not really matter for the total call-time, if you were successfully:
- reducing the __cdecl Call-Overhead from e.g. 100nano-seconds to perhaps 10nano-seconds with ASM-thunking
- when the sqlite3_exec method itself takes about 10 micro-seconds for its internal instructions in addition
To write it up in numbers... the total call-time for sqlite3_exec:
- would be about 10.1 micro-seconds (using the established cdecl-call-workarounds without any ASM-tricks)
- and it might be about 10.01 micro-seconds, if you manage the ASM-trickery successfully
Congratulations then (in case you manage the ASM-trickery).
You will then have succeeded, to call the sqlite3_exec function:
- only about 1% faster over all (compared to using the established, stable VB6-cdecl calling methods alternatively)
- whilst introducing a whole lot of potentially unstable, barely maintainable thunking-code into your App
Not a good bargain at all, if you ask me.
Olaf
-
Re: hao to call Sqlite3.dll with cdecl?
sqlite3_exec,This function is 主要问题还是在于读写大量单元格十万个。The main problem is still reading and writing a large number of cells.It took me five seconds to read and write one compo我在读写Excel表格的一个组件中五万行十五列,用了五秒钟。I spent five seconds reading and writing fifty thousand rows and fifteen columns in one component of an Excel spreadsheet.it'S stdcall,if it'是cdecl,It could take 30 seconds.
-
Re: hao to call Sqlite3.dll with cdecl?
only use jmp。I don't think this will bring any performance loss.
JmpBackAddr = DllFunAddr - BackFunAddr - 5
Code(0) = &HE9
However, this format does not support CDMAHowever, this format does not support cdeclI
also can make a vb com objet to call,maybe slowly
-
Re: hao to call Sqlite3.dll with cdecl?
DispCallFunc
methond 2:(by com),which quickly
Code:
'FunctionPtr.cls '函数指针类的定义
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DatasourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "FunctionPtr"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Private Const DISPATCH_METHOD = &H1
Private Const LOCALE_SYSTEM_DEFAULT = &H800
Private Const DISPID_VALUE = 0
Private Enum CALLCONV
CC_FASTCALL = 0
CC_CDECL = 1
CC_MSCPASCAL = CC_CDECL + 1
CC_PASCAL = CC_MSCPASCAL
CC_MACPASCAL = CC_PASCAL + 1
CC_STDCALL = CC_MACPASCAL + 1
CC_FPFASTCALL = CC_STDCALL + 1
CC_SYSCALL = CC_FPFASTCALL + 1
CC_MPWCDECL = CC_SYSCALL + 1
CC_MPWPASCAL = CC_MPWCDECL + 1
CC_MAX = CC_MPWPASCAL + 1
End Enum
Private Type PARamdATA
szName As String
vt As VariantTypeConstants
End Type
Private Type METHODDATA
szName As String
ppdata As Long '/* pointer to an array of PARAMDATAs */
dispid As Long '/* method ID */
iMeth As Long '/* method index */
cc As CALLCONV '/* calling convention */
cArgs As Long '/* count of arguments */
wFlags As Integer '/* same wFlags as on IDispatch::Invoke() */
vtReturn As Integer
End Type
Private Type INTERFACEDATA
pmethdata As Long '/* pointer to an array of METHODDATAs */
cMembers As Long
End Type
Private Declare Function CreateDispTypeInfo Lib "oleaut32" (ByRef pidata As INTERFACEDATA, ByVal lcid As Long, ByRef pptinfo As IUnknown) As Long
Private Declare Function CreateStdDispatch Lib "oleaut32" (ByVal punkOuter As IUnknown, ByRef pvThis As Delegator, ByVal ptinfo As IUnknown, ByRef ppunkStdDisp As IUnknown) As Long
Private Type VTable
pThunk As Long
End Type
Private Type Delegator
pVtbl As Long
pFunc As Long
End Type
Private m_Thunk(5) As Long
Private m_VTable As VTable
Private m_Delegator As Delegator
Private m_InterfaceData As INTERFACEDATA
Private m_MethodData As METHODDATA
Private m_ParamData() As PARAMDATA
Private m_FunctionPtr As Object
Public Function Create(ByVal pFunc As Long, ByVal RetType As VariantTypeConstants, ParamArray ParamTypes() As Variant) As Object
If TypeName(m_FunctionPtr) <> "Nothing" Then
Set Create = m_FunctionPtr
Exit Function
End If
Dim i As Long
Dim p As Long
Dim cParam As Long
cParam = UBound(ParamTypes) + 1
ReDim m_ParamData(cParam)
If cParam Then
For i = 0 To cParam - 1
m_ParamData(i).vt = ParamTypes(i)
m_ParamData(i).szName = ""
Next
End If
m_MethodData.szName = "Invoke"
m_MethodData.ppdata = VARPtr(m_ParamData(0))
m_MethodData.dispid = DISPID_VALUE
m_MethodData.iMeth = 0
m_MethodData.cc = CC_STDCALL
m_MethodData.cArgs = cParam
m_MethodData.wFlags = DISPATCH_METHOD
m_MethodData.vtReturn = RetType
m_InterfaceData.pmethdata = VarPtr(m_MethodData)
m_InterfaceData.cMembers = 1
Dim ti As IUnknown
Dim Result As IUnknown
Set Result = Nothing
i = CreateDispTypeInfo(m_InterfaceData, LOCALE_SYSTEM_DEFAULT, ti)
If i = 0 Then
m_VTable.pThunk = VarPtr(m_Thunk(0))
m_Delegator.pVtbl = VarPtr(m_VTable)
m_Delegator.pFunc = pFunc
p = VarPtr(m_InterfaceData)
p = VarPtr(m_Delegator)
i = CreateStdDispatch(Nothing, m_Delegator, ti, Result)
If i = 0 Then
Set m_FunctionPtr = Result
Set Create = m_FunctionPtr
End If
End If
End Function
Private Sub Class_Initialize()
'thunk的机器码,加nop是为了清晰
m_Thunk(0) = &H4244C8B 'mov ecx, [esp+4] 获得this pointer
m_Thunk(1) = &H9004418B 'mov eax, [ecx+4] nop 获得m_pFunc
m_Thunk(2) = &H90240C8B 'mov ecx, [esp] nop 得到返回地址
m_Thunk(3) = &H4244C89 'mov [esp+4], ecx 保存返回地址
m_Thunk(4) = &H9004C483 'add esp, 4 nop 重新调整堆栈
m_Thunk(5) = &H9090E0FF 'jmp eax 跳转到m_pFunc
End Sub
'Helper.cls '其实不是Helper,只是原来的名字而已,包含供测试的函数
Attribute VB_Name = "Helper"
Option Explicit
Sub Test1(ByRef this As Long)
MsgBox "Test1", vbOKOnly, "hehe"
End Sub
Sub Test(ByVal s As String)
MsgBox s, vbOKOnly, "hehe"
End Sub
'测试程序
Option Explicit
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Sub Form_Load()
Dim p As FunctionPtr
Set p = New FunctionPtr
Dim d As Object
Set d = p.Create(AddressOf Test, vbEmpty, vbString)
d.Invoke ("hehe")
Dim hModUser32
Dim pMessageBoxW As Long
hModUser32 = GetModuleHandle("User32")
pMessageBoxW = GetProcAddress(hModUser32, "MessageBoxW")
Dim mbw As New FunctionPtr
Dim MessageBoxW As Object
Set MessageBoxW = mbw.Create(pMessageBoxW, vbLong, vbLong, vbString, vbString, vbLong)
'MessageBoxA 0, "hehe,form MessageBoxA", "", 0
MessageBoxW.Invoke 0, "hehe,form MessageBoxW", "", 0
End Sub
-
Re: hao to call Sqlite3.dll with cdecl?
-
Re: hao to call Sqlite3.dll with cdecl?
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
The trick
I though about tweaking the trampolines but for cdecl it would be more complicated.
After the function returns the thunk will have to adjust stack with add esp, X to clear the arguments before returning control to caller function.
So on entry the stack is ret_addr, arg1, arg2, arg3, ..., argN which has to be shuffled into arg1, arg2, arg3, ..., argN, ret_addr so to be able to execute a simple call cdecl_function : add esp, args_size : ret
So this needs a rep movsb organized for the args on the stack (preserving esi/edi/ecx in the meantime) which is a bit more code that cannot be fit in 8 bytes as the original trampolines.
cheers,
</wqw>
-
1 Attachment(s)
Re: hao to call Sqlite3.dll with cdecl?
wqweto, you could just save the ret_addr elsewhere like into unused last arg.
For example:
Code:
BITS 32
NUM_OF_ARGS equ 4
pop eax ; get retaddr
pop ecx ; get pfn
mov [esp + NUM_OF_ARGS * 4], eax
call ecx
add esp, NUM_OF_ARGS * 4
ret
The corresponding VB6 function has the following form:
Code:
Public Function CallCdecl4( _
ByVal pfn As Long, _
ByVal lArg1 As Long, _
ByVal lArg2 As Long, _
ByVal lArg3 As Long, _
ByVal lArg4 As Long, _
Optional ByVal lRetSpace As Long) As Long
End Function
I've made small test project where you can call different C-runtime functions:
Code:
Option Explicit
Private Declare Function LoadLibrary Lib "kernel32" _
Alias "LoadLibraryW" ( _
ByVal lpLibFileName As Long) As Long
Private Declare Function GetProcAddress Lib "kernel32" ( _
ByVal hModule As Long, _
ByVal lpProcName As String) As Long
Sub Main()
Dim hMSVCrt As Long
Dim pfn_snwprintf As Long
Dim pfn_ultow As Long
Dim pfn_wcsupr As Long
Dim pfn_wstrtime_s As Long
Dim sBuffer As String
hMSVCrt = LoadLibrary(StrPtr("msvcrt"))
pfn_snwprintf = GetProcAddress(hMSVCrt, "_snwprintf")
pfn_ultow = GetProcAddress(hMSVCrt, "_ultow")
pfn_wcsupr = GetProcAddress(hMSVCrt, "_wcsupr")
pfn_wstrtime_s = GetProcAddress(hMSVCrt, "_wstrtime_s")
sBuffer = String$(255, vbNullChar)
CallCdecl4 pfn_snwprintf, StrPtr(sBuffer), Len(sBuffer), StrPtr("Test %ld"), 1234
Debug.Print sBuffer
CallCdecl3 pfn_ultow, &H80212123, StrPtr(sBuffer), 10
Debug.Print sBuffer
CallCdecl2 pfn_wstrtime_s, StrPtr(sBuffer), Len(sBuffer)
Debug.Print sBuffer
sBuffer = "HeLlO WoRlD!!!"
CallCdecl1 pfn_wcsupr, StrPtr(sBuffer)
Debug.Print sBuffer
End Sub
You just need to install the Add-in.
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
The trick
wqweto, you could just save the ret_addr elsewhere like into unused last arg.
Aaaa, this is a nice one!
Probably something like this would work
Code:
0: 58 pop eax
1: 89 84 24 XX XX XX XX mov dword ptr [esp+Xh],eax
8: 58 pop eax
9: FF D0 call eax
11: 90 nop
12: 90 nop
13: 90 nop
14: 81 C4 XX XX XX XX add esp,Xh
20: C3 ret
21: 90 nop
22: 90 nop
23: 90 nop
&H24848958, X, &H90D0FF58, &HC4819090, X, &H909090C3
Didn't test it though.
cheers,
</wqw>
-
Re: hao to call Sqlite3.dll with cdecl?
I would like to see an example, where we prepare an execution buffer, adding machine code and a pointer to a vb function, say in a module, so when we call that execution buffer, the machine code call back the function (or sub) in the module.
I can use this to prepare from my M2000 interpreter compiled parts which when run can use modules from the M2000 environment, to print in the M2000 console (which is a picture box on a form).
-
Re: hao to call Sqlite3.dll with cdecl?
> so when we call that execution buffer. . .
How do you call an execution buffer in VB6 is the problem. There is no need for an execution buffer to callback a function, just call the address of the function if you have a solution to the problem at hand, namely if you have an address of a function (external stdcall DLL or in a bas module w/ AddressOf MyFunction for instance) how do you call this function, pass parameters and receive result proper?
Trampolines can solve this problem with minimal overhead.
In this thread we discuss tweaking such trampolines to call cdecl compiled functions in external C/C++ DLLs like sqlite3.dll
cheers,
</wqw>
-
Re: hao to call Sqlite3.dll with cdecl?
I can't understand your answer wqweto. Ok I know the scope of this thread is for trampolines for loaded functions. My word was for functions that we prepare in memory, say with cdecl convention call, and for call back from that functions. I have no idea how to do that. Sometime ago Trick response to me, but I didn't understood also. I use to write assembly for 6502, and some time for 8086, but I have no clear idea about the prolog and epilog for the calling. Also what happen if we stop execution on the call back function when we call it form machine code on IDE?
-
Re: hao to call Sqlite3.dll with cdecl?
This example uses DispCallFunc to call the dynamic code:
Code:
Option Explicit
Private Const HEAP_CREATE_ENABLE_EXECUTE As Long = &H40000
Private Const HEAP_NO_SERIALIZE As Long = &H1
Private Declare Function HeapCreate Lib "kernel32" ( _
ByVal flOptions As Long, _
ByVal dwInitialSize As Long, _
ByVal dwMaximumSize As Long) As Long
Private Declare Function HeapDestroy Lib "kernel32" ( _
ByVal hHeap As Long) As Long
Private Declare Function HeapAlloc Lib "kernel32" ( _
ByVal hHeap As Long, _
ByVal dwFlags As Long, _
ByVal dwBytes As Long) As Long
Private Declare Function HeapFree Lib "kernel32" ( _
ByVal hHeap As Long, _
ByVal dwFlags As Long, _
ByRef lpMem As Any) As Long
Private Declare Function GetMem4 Lib "msvbvm60" ( _
ByRef pSrc As Any, _
ByRef pDst As Any) As Long
Private Declare Function DispCallFunc Lib "oleaut32.dll" ( _
ByRef pvInstance As Any, _
ByVal oVft As Long, _
ByVal cc As Long, _
ByVal vtReturn As VbVarType, _
ByVal cActuals As Long, _
ByRef prgvt As Any, _
ByRef prgpvarg As Any, _
ByRef pvargResult As Variant) As Long
Sub Main()
Dim pCode As Long
Dim hHeap As Long
Dim vRet As Variant
hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE Or HEAP_NO_SERIALIZE, 0, 0)
pCode = HeapAlloc(hHeap, 0, 8)
' // Put code
' // mov eax, XXXXXXX
' // call eax
' // ret
GetMem4 &HB8&, ByVal pCode
GetMem4 &HC3D0FF00, ByVal pCode + 4
' // Add callback
GetMem4 FAR_PROC(AddressOf Callback), ByVal pCode + 1
' // Call dynamic code (STDCALL)
DispCallFunc ByVal 0&, pCode, 4, vbLong, 0, ByVal 0&, ByVal 0&, vRet
Debug.Print vRet
HeapFree hHeap, 0, ByVal pCode
HeapDestroy hHeap
End Sub
Private Function FAR_PROC( _
ByVal pfn As Long) As Long
FAR_PROC = pfn
End Function
Private Function Callback() As Long
Callback = 1234567
End Function
Alternatively you could calculate the relative CALL instruction but it requires an additional calculation. PUSH addr/RET sequence can be used as well.
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
georgekar
My word was for functions that we prepare in memory, say with cdecl convention call, and for call back from that functions. I have no idea how to do that.
You can use Visual Studio to write various functions with cdecl and stdcall calling conventions and so on (varargs etc.), call these from main and disassemble the emitted callsite code (with Ctrl+Alt+D shortcut) directly in VS IDE.
This is what I usually do, certainly don't write ASM thunks by hand but use the comfortable VS IDE like this:
Code:
__declspec(naked) void asm_test()
{
__asm {
pop eax
mov [esp + 4*0x123456], eax
pop eax
call eax
nop
nop
nop
add esp, 4*0x123456
ret
nop
nop
nop
}
}
void __cdecl main()
{
int *p = (int *)asm_test;
printf("&H%08X, &H%08X, &H%08X, &H%08X, &H%08X, &H%08X\n", p[0], p[1], p[2], p[3], p[4], p[5]);
. . .
cheers,
</wqw>
-
Re: hao to call Sqlite3.dll with cdecl?
Very Good. Supposed I want to call with a parameter, or two (as long, say pointers to anything). Trick show the way to call a function from asm, but without passing something to it. Alternative I can use another buffer to put what I want and the call back just take it from that buffer.
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
This is what I usually do, certainly don't write ASM thunks by hand but use the comfortable VS IDE like this
Why do you use so many nops?
BTW i use OllyDbg for small thunks:
https://www.youtube.com/watch?v=XCLdBmw5q_8
-
Re: hao to call Sqlite3.dll with cdecl?
georgekar,
please provide more information: what are parameters, how many ones, what's the function, what should it do?
-
Re: hao to call Sqlite3.dll with cdecl?
1. For SQLITE3, the sqite3 exec functions get a call back. Can I pass a vb6 module's sub or function? I have to prepare it with FAR_PROC function ?
https://stackoverflow.com/questions/...ation/31168999
2. I think that winsqlite3.dll, has no use of password (like we did in an MDB database). Is there any other sqlite3 dll which we can use and with enabled the password option? (I know the mr Olaf has in RCX (5, 6) the solution, but as you know I prefer something which I can study and perhaps change to suit my taste).
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
georgekar
You should prepare trampolin to the stack conversion like that:
Code:
Option Explicit
Private Const HEAP_CREATE_ENABLE_EXECUTE As Long = &H40000
Private Const HEAP_NO_SERIALIZE As Long = &H1
Private Declare Function HeapCreate Lib "kernel32" ( _
ByVal flOptions As Long, _
ByVal dwInitialSize As Long, _
ByVal dwMaximumSize As Long) As Long
Private Declare Function HeapDestroy Lib "kernel32" ( _
ByVal hHeap As Long) As Long
Private Declare Function HeapAlloc Lib "kernel32" ( _
ByVal hHeap As Long, _
ByVal dwFlags As Long, _
ByVal dwBytes As Long) As Long
Private Declare Function HeapFree Lib "kernel32" ( _
ByVal hHeap As Long, _
ByVal dwFlags As Long, _
ByRef lpMem As Any) As Long
Private Declare Function GetMem4 Lib "msvbvm60" ( _
ByRef pSrc As Any, _
ByRef pDst As Any) As Long
Private Declare Function GetMem1 Lib "msvbvm60" ( _
ByRef pSrc As Any, _
ByRef pDst As Any) As Long
Private Declare Function DispCallFunc Lib "oleaut32.dll" ( _
ByRef pvInstance As Any, _
ByVal oVft As Long, _
ByVal cc As Long, _
ByVal vtReturn As VbVarType, _
ByVal cActuals As Long, _
ByRef prgvt As Any, _
ByRef prgpvarg As Any, _
ByRef pvargResult As Variant) As Long
Private m_hHeap As Long
Sub Main()
Dim pTrampoline As Long
pTrampoline = PrepareCallbackTrampolinCDecl(AddressOf callback, 4)
' // Test
MsgBox ApiCall(pTrampoline, vbLong, 1, 2, 3, 4)
If pTrampoline Then HeapFree m_hHeap, 0, ByVal pTrampoline - 4
If m_hHeap Then HeapDestroy m_hHeap
End Sub
Private Function PrepareCallbackTrampolinCDecl( _
ByVal pfnCallback As Long, _
ByVal bArgs As Byte) As Long ' // Args should be less 32
Dim pCode As Long
If m_hHeap = 0 Then
m_hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE Or HEAP_NO_SERIALIZE, 0, 0)
If m_hHeap = 0 Then
Exit Function ' // out of memory
End If
End If
pCode = HeapAlloc(m_hHeap, 0, 24)
GetMem4 &HA358&, ByVal pCode + 4
GetMem4 &HE80000, ByVal pCode + 8
GetMem4 &H83000000, ByVal pCode + 12
GetMem4 &H25FF10EC, ByVal pCode + 16
' // Update references
GetMem4 pCode, ByVal pCode + 6
GetMem4 pfnCallback - (pCode + &HF), ByVal pCode + 11
GetMem4 pCode, ByVal pCode + 20
GetMem1 bArgs * 4, ByVal pCode + 17
PrepareCallbackTrampolinCDecl = pCode + 4
End Function
Private Function callback( _
ByVal data As Long, _
ByVal argc As Long, _
ByVal ppargv As Long, _
ByVal ppazColName As Long) As Long
' // ...
MsgBox data & " " & argc & " " & ppargv & " " & ppazColName
callback = 12345
End Function
Private Function ApiCall( _
ByVal pfn As Long, _
ByVal retType As VbVarType, _
ParamArray params() As Variant) As Variant
Dim types() As Integer
Dim list() As Long
Dim param() As Variant
Dim pIndex As Long
Dim ptrList As Long
Dim ptrTypes As Long
Dim resultCall As Long
Dim hLib As Long
Dim funcAddress As Long
Const CC_CDECL As Long = 1
If LBound(params) <= UBound(params) Then
ReDim list(LBound(params) To UBound(params))
ReDim types(LBound(params) To UBound(params))
ReDim param(LBound(params) To UBound(params))
For pIndex = LBound(params) To UBound(params)
param(pIndex) = params(pIndex)
list(pIndex) = VarPtr(param(pIndex))
types(pIndex) = VarType(param(pIndex))
Next
ptrList = VarPtr(list(LBound(list)))
ptrTypes = VarPtr(types(LBound(types)))
End If
resultCall = DispCallFunc(ByVal 0&, _
pfn, _
CC_CDECL, _
retType, _
UBound(params) - LBound(params) + 1, _
ByVal ptrTypes, _
ByVal ptrList, _
ApiCall)
If resultCall Then Err.Raise 5: Exit Function
End Function
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
georgekar
..
2. I think that winsqlite3.dll, has no use of password (like we did in an MDB database). Is there any other sqlite3 dll which we can use and with enabled the password option? (I know the mr Olaf has in RCX (5, 6) the solution, but as you know I prefer something which I can study and perhaps change to suit my taste).
SQLite Encryption Extension
https://www.sqlite.org/see/doc/trunk/www/readme.wiki
-
Re: hao to call Sqlite3.dll with cdecl?
Thanks, Trick.
@Arnoutdv, is any ready to use dll, or I have to compile one?
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
The trick
Why do you use so many nops?
NOPs do not take any CPU cycles on execution nowadays but I use these to align following offsets in the thunk so to make "codegen" of the variable NUM_OF_ARGS easier like this
Code:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function VirtualProtect Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Public Function Call_ultow(ByVal Pfn As Long, ByVal Value As Long, ByVal Str As Long, ByVal Radix As Long, Optional ByVal Spacer As Long) As Long
pvPatchTrampoline AddressOf Module1.Call_ultow, 3
Call_ultow = Call_ultow(Pfn, Value, Str, Radix)
End Function
Private Function pvPatchTrampoline(ByVal Pfn As Long, ByVal lNumParams As Long) As Boolean
Const PAGE_EXECUTE_READWRITE As Long = &H40
Const THUNK_SIZE As Long = 21
Dim bInIDE As Boolean
Dim aThunk(0 To 5) As Long
Debug.Assert pvSetTrue(bInIDE)
If bInIDE Then
Call CopyMemory(Pfn, ByVal Pfn + &H16, 4)
Else
Call VirtualProtect(Pfn, THUNK_SIZE, PAGE_EXECUTE_READWRITE, 0)
End If
' 0: 58 pop eax
' 1: 89 84 24 XX XX XX XX mov dword ptr [esp+Xh],eax
' 8: 58 pop eax
' 9: FF D0 call eax
' 11: 90 nop
' 12: 90 nop
' 13: 90 nop
' 14: 81 C4 XX XX XX XX add esp,Xh
' 20: C3 ret
aThunk(0) = &H24848958
aThunk(1) = lNumParams * 4 + 4
aThunk(2) = &H90D0FF58
aThunk(3) = &HC4819090
aThunk(4) = lNumParams * 4
aThunk(5) = &HC3
Call CopyMemory(ByVal Pfn, aThunk(0), THUNK_SIZE)
'--- success
pvPatchTrampoline = True
End Function
Private Function pvSetTrue(bValue As Boolean) As Boolean
bValue = True
pvSetTrue = True
End Function
This way Call_ultow is a self-modifying trampoline to a cdecl pfn that can be used like this
Code:
Option Explicit
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 Sub Form_Click()
Dim hLib As Long
Dim Pfn As Long
Dim sBuffer As String
hLib = LoadLibrary("msvcrt")
Pfn = GetProcAddress(hLib, "_ultow")
sBuffer = String(50, 0)
Call_ultow Pfn, &H80212123, StrPtr(sBuffer), 10
MsgBox "[" & Replace(sBuffer, vbNullChar, vbNullString) & "]"
End Sub
The extra Spacer parameter was the invention in this thread. Kudos!
cheers,
</wqw>
-
Re: hao to call Sqlite3.dll with cdecl?
I want call by vb function,without any api like resultCall = DispCallFunc
Private Declare Function LoadLibrary Lib "kernel32"
it'S also can bind to vb function or getprocaddress from load dll to memory.
in first can make Wrapper or write vb function asm code.
I will test which is Fastest。
maybe DispCallFunc or "CallWindowProcA",someone is very slowly.
which api call is best quickly?
which asm is best?
Although we can use a lot of ways to achieve, but the speed really varies a lot. We hope to find the best solution, but at the same time, each solution can be used as a reference for learning, so that we can improve the technology to a higher level.
chinese:虽然我们可以用很多种方法去实现,但是速度真的相差很多。我们希望能够找到一种最佳的方案,但同时每一个方案都可以作为学习参考,这样我们才能够把技术提高到更高的境界。
-
Re: hao to call Sqlite3.dll with cdecl?
xiaoyao i've already suggested TLB and my Add-in which is faster. The other approach https://www.vbforums.com/showthread....g-functions-by the pointer but you have to change to support cdecl.
-
Re: hao to call Sqlite3.dll with cdecl?
Public Function CallCdecl( _
ByVal pfn As Long, _
ByVal lArg1 As Long, _
Optional ByVal lRetSpace As Long) As Long
End Function
Public Public Function CallCdecl2( _
ByVal pfn As Long, _
ByVal lArg1 As Long, _
ByVal lArg2 As Long, _
Optional ByVal lRetSpace As Long) As Long
End Function
Function CallCdecl3( _
ByVal pfn As Long, _
ByVal lArg1 As Long, _
ByVal lArg2 As Long, _
ByVal lArg3 As Long, _
Optional ByVal lRetSpace As Long) As Long
End Function
Public Function CallCdecl4( _
ByVal pfn As Long, _
ByVal lArg1 As Long, _
ByVal lArg2 As Long, _
ByVal lArg3 As Long, _
ByVal lArg4 As Long, _
Optional ByVal lRetSpace As Long) As Long
End Function
how to remove lRetSpace,only like:
Public Function CallCdecl( _
ByVal pfn As Long, _
ByVal lArg1 As Long) As Long
CallCdecl=1 'chang code by asm
End Function
My idea is to construct five to ten general-purpose function can call all the APi after all.
This is a one-size-fits-all approach, and I very much agree that t这是一种万能的方法,非常通用,当然最好的方法还是和原来的函数原型一模一样。It's a one-size-fits-all approach, very versatile. Of course, the best way is still the same as the original function prototype. Both of these methods are 这两种方法都是很好的,我们可以研究一下,每个人按照自己需要去使用。This is a universal method and very versatile. Of course, the best way is to be exactly the same as the original function prototype. Both of these methods are very good, we can study each person to use according to actual needs
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
The trick
I think I already had the same trampoline thunk tweaked for cdecl in my previous post or is it a different one?
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
xiaoyao
I spent five seconds reading and writing fifty thousand rows and fifteen columns in one component of an Excel spreadsheet.
Could you please post this test-project (with working code, as a *.zip, including the Excel-File) -
so that one can see better, what the whole thing "is all about"?
Olaf
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
wqweto
I think I already had the same trampoline thunk tweaked for cdecl in my previous post or is it a different one?
dose it support cdecl dll api?
-
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
xiaoyao
dose it support cdecl dll api?
In the snippet above Pfn is a cdecl function pointer to _ultow function in msvcrt DLL
Code:
hLib = LoadLibrary("msvcrt")
Pfn = GetProcAddress(hLib, "_ultow")
Implementing your CallCdecl, CallCdecl2, CallCdecl3 and CallCdecl4 is trivial using the Call_ultow function as a model but you cannot get rid of its Spacer parameter easy.
The extra paramter is needed to simplify the thunk to 21 bytes only but feel free to enhance it with rep movsb and all the other necessary instructions to shuffle the parameters on the stack as discussed above. This would allow indeed not having an extra optional Spacer parameter on your CallCdeclXxx functions.
cheers,
</wqw>
-
Re: hao to call Sqlite3.dll with cdecl?
CAN YOU GIVE ME 6 SAMPLE?
CallCdecl, CallCdecl2, CallCdecl3 and CallCdecl4 ,CallCdecl5,CallCdecl6
put asm to address(funaddress, ParamArray params() As Variant) As Variant
For pIndex = 0 To UBound(params)
PUT ASM "rep movsb " & pIndex ×4
NEXT
LIKE THIS?
-
Re: hao to call Sqlite3.dll with cdecl?
I already put more effort in this thread than I intended to, so I'll leave stack shuffling implementation to you.
Now I'll go read some extra info about the great Visual Freebasic of China instead -- we already have enough links on topics about it here, don't we?
cheers,
</wqw>