Re: hao to call Sqlite3.dll with cdecl?
cdecl declare sub api1 lib "abc.dll" (destination as any, source as any, byval length as long)
cdecl declare function api2 lib "abc.dll" (destination as any, source as any, byval length as long) as long
how to write asm to vb function for call cdecl
sub api1(a,b,c)
msgbox "put asm"
end sub
function api2(a,b,c) as long
'
end function
sqlite3.dll only An example 。
Re: hao to call Sqlite3.dll with cdecl?
address1=GetProADDRESS (dll,"sqlite3_exec")
bind_dllto_address(address1,addressof Mysqlite3_exec,args=2)
function Mysqlite3_exec(ByVal sqlite3 As Long, ByVal zSql As long)
'ASMCODE:
'CALL address1(sqlite3 ,zSql )
'clear something?
end function
PatchTrampoline AddressOf Module1.CallCdecl1, 1
PatchTrampoline AddressOf Module1.CallCdecl2, 2
=========
can chang CallCdecl2 without (ByVal Pfn As Long, Optional ByVal Space。
General method of a few parameters, as long as the five functions can be called almost all the API functions.
The speed of this operation is very fast.
new ide(visual freebasic support cdecl,)But the most intuitive way is to write one for each function.
how to realize this?
The main principle is to open the software for the first time, the address of all these functions, the number of parameters compiled into the compilation, the real call is just to read a few parameters can be.
主要原理就是第一次打开软件,把这些所有的函数地址,参数数量用汇编写入进去,真正调用的时候只是读取几个参数就可以。
function Mysqlite3_exec(ByVal sqlite3 As Long, ByVal zSql As long)
'
end function
Some people may misunderstand that I am advertising, the software itself is free. Freebasic is a language that was first used to compile support for Qbasic. Technology without borders, VB6 has been dead for 23 years, we this. This theme is mainly to enhance some of its functions, but this is limited after all.
visual freebasic are easy to use, more than VB6
But the operation com object is very troublesome, hoped that has the ability person to solve him together.
like sok=invoke(objptr,vblong,vblong)
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
xiaoyao
... visual freebasic are easy to use, more than VB6 ...
No, it isn't "easier to use" (for complex scenarios), as long as it does not:
- come with proper Class-definition support
- and proper Event-support on these Classes (WithEvents-support, RaiseEvent-support)
- and proper "generalized Error-Handling" when interacting with the Methods of these Classes
Quote:
Originally Posted by
xiaoyao
... the operation com object is very troublesome, ...
like sok=invoke(objptr,vblong,vblong)
The COM-signature you described above:
HResult hr = SomeVoidReturningFunc(ClassType * ThisPtr, int Arg1 , int Arg2)
or
HResult hr = SomeIntReturningFunc(ClassType * ThisPtr, int Arg1 , int Arg2, [out, retval] int * Result)
is a necessity when interacting with "Object-Methods, that shall transport Error-state".
You cannot avoid or circumvent this call-scheme.
Besides, it was already mentioned, that the slight call-overhead of such Object-Methods -
(due to "one more arg" in case of a void-method, and "two more args" in case of a value-returning method) -
is timing-wise not really significant, when the method-body performs more than a simple: return a + b internally.
BTW, you still have not provided some zipped CodeArchive, where you demonstrate what you need this "fast sqlite-calling" for.
You mentioned, that you "gave proof" that "some thing" was faster than "some other thing" -
but such statements are just "gobbledigook", as long as you don't provide real proof via some Test-Code which supports your claims also on the machines of other developers.
You never do that (posting your own code for something) - the only thing you do so far is "making wild claims" (in very badly translated english).
Since you are still unfamiliar with VB6-code apparently -
I'd personally have no problem when you'd post your "proofs" in a zipped freebasic *.bas module instead -
but please post at least "something" when you want us to take you seriously.
Olaf
1 Attachment(s)
Re: hao to call Sqlite3.dll with cdecl?
main code in reply:#48
can't upload cdecl.dll (api=Add),sorry!
Add(11,22)=33
DOWN test: Attachment 179493
Some people are not interested in this at all. Those who are interested in it will write an example to test. Using other programming languages to generate a cdecl API of addition operation, DLL file is on the line. Hard work, because I used to test a cdecl V8 JS calculation, and SQLite has nothing to do with it. All these DLL files are not allowed to be uploaded.
In fact, my focus is not on how to handle SQLite, but on how to call cdecl API to minimize the overhead
how to call cdecl if fast,you can try.
sorry,my code is too much ,and i put the testcode ,you can try yourself.
i put more method for call cdecl,now i add one again.
'Rmlistview.rar cCDECL.cls
'http://read.pudn.com/downloads80/sourcecode/others/306578/listview/32bpp%20DIB/cCDECL.cls__.htm
test:times=50 , fotnext=100000
Call Cdecl dll api ,UsedTime:
cCDECL.CLS--2389.5272 MS
Call Cdecl dll api ,UsedTime:
VbAddRef--103.6018 MS
VbAdd--99.4034 MS
CallCdecl--153.6503 MS
Com vTable--3129.5649 MS
DispCallFunc--4215.9675 MS
ClassAdd--237.5009 MS
ClassAddRef--246.6976 MS
ClassFriendAdd--109.4997 MS
Code:
Dim Lib_cCDECL As New cCDECL
'C = Lib_cCDECL.CallFuncAddress(ExcuteJavaScript_Ptr, a, b)
With Lib_cCDECL
For K = 1 To KMAX
For i = 1 To Count
a = i
b = i * 2
QueryPerformanceCounter CPUv1
ret = .CallFuncAddress(ExcuteJavaScript_Ptr, a, b)
QueryPerformanceCounter CPUv2
CusedTime = (CPUv2 - CPUv1) / MsCpu
TimeSz(8) = TimeSz(8) + CusedTime
Next
Next
End With
down test Attachment 179493
Help
1.95 MB of 9.54 MB Used(why not 1000mb?)
File Upload Manager - Manage all files that you have uploaded
Re: hao to call Sqlite3.dll with cdecl?
For Windows 10 I have this in codebank:
https://www.vbforums.com/showthread....winsqlite3-dll
I dodn't know if the internal SQlite3 of Windows 10 can use password protection. But all other functions performed as expected.
Re: hao to call Sqlite3.dll with cdecl?
how to fix this for call cdecl?
MakeFunctionCdecl ExcuteJavaScript_Ptr, AddressOf MyAdd, 2
Public Sub MakeFunctionCdecl(DllFunAddr As Long, BackFunAddr As Long, Args As Long)
Dim code() As Byte, JmpBackAddr As Long
Dim OldProtect As Long
Dim ByteLen As Long
Args = 2
ByteLen = 16
ReDim code(ByteLen)
Vblegend.VirtualProtect ByVal DllFunAddr, ByteLen, 64, OldProtect '更改函数地址所在页面属性
JmpBackAddr = DllFunAddr - BackFunAddr - 5
code(0) = &HE9
CopyMemory code(1), JmpBackAddr, 4
Dim i As Long
code(5) = &H90
code(6) = &H90
code(7) = &H90
code(8) = &H81
code(9) = &HC4
code(10) =Args *4
code(11) = &HC3
' 11: 90 nop
' 12: 90 nop
' 13: 90 nop
' 14: 81 C4 XX XX XX XX add esp,Xh
' 20: C3 ret
Vblegend.WriteProcessMemory -1, ByVal BackFunAddr, code(0), ByteLen, 0
End Sub
Re: hao to call Sqlite3.dll with cdecl?
You cannot "fix" this. The logic is broken.
When you JMP to DllFunAddr the function there wil RET to the original address of the caller so your ADD ESP, Xh will not be reached at all.
I already told you what needs to be done: shuffle the args so that a *new* return address is inserted on the stack, namely the address of your ADD ESP, Xh + RET thunk.
Shuffling args with REP MOVSB will be slower that PUSH-ing one more additional param as the original solution proposed by The Trick in the thread.
I know you'd love to micro-benchmark it with yet another flowed benchmark of yours. This
Code:
QueryPerformanceCounter CPUv1
ret = .CallFuncAddress(ExcuteJavaScript_Ptr, a, b)
QueryPerformanceCounter CPUv2
. . . is wrong on so many levels. You cannot benchmark like this as the performance counters are not precise enough. It's impossible to measure couple of instructions with QueryPerformanceCounter. This API takes a lot more that couple of instructions to execute and the mutlimedia timer it's using is not precise enough.
Suppose you have functions f and g. You have to benchmark a loop of million executions for f (A), then for g (B) and finally million executions of an empty loop (C) then compare A - C vs B - C.
cheers,
</wqw>
Re: hao to call Sqlite3.dll with cdecl?
MAYBE NOT USE JMP,USE call eax?
my friend write asm code,it's run successful,but i lost the code,He can't be reached now。
' 9: FF D0 call eax
Code:
push 1
push 2
call function
add esp, 8
like this?
function myAdd(byval a as long ,byval b as long) as long
push b
push a
call function (cdecl api ptr)
add esp, 8
end function
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
xiaoyao
Call Cdecl dll api ,UsedTime:
VbAddRef--103.6018 MS
VbAdd--99.4034 MS
CallCdecl--153.6503 MS
Com vTable--3129.5649 MS
DispCallFunc--4215.9675 MS
ClassAdd--237.5009 MS
ClassAddRef--246.6976 MS
ClassFriendAdd--109.4997 MS
cCDECL.CLS--2389.5272 MS
down test
Attachment 179493
Yep, that's just another of your "Micro-Benchmarks" (which measure only call-overhead - and leave out the work within a function-body).
And BTW - your results above are, what comes out when you run the test in the IDE.
For a more real-world-test regarding call-overheads, you should compile natively (with all extended compiler-options checked).
I've just did that with your code (using the cdecl.dll which implemented the little Add-function) -
compiling the whole thing natively (with all extended options checked) -
and also including (just for fun) the RC5/RC6 built-in cdecl-call-helper (instead of the cCDecl-Class of Paul Caton).
Here's the code I've used, to replace Catons cCDecl class in your Module1:
Code:
'With Lib_cCDECL
'For K = 1 To TimesVal
'For i = 1 To Imax
' a = i
' b = i * 2
' QueryPerformanceCounter CPUv1
' Ret = .CallFuncAddress(ExcuteJavaScript_Ptr, a, b)
' QueryPerformanceCounter CPUv2
' CusedTime = (CPUv2 - CPUv1) / MsCpu
' TimeSz(7) = TimeSz(7) + CusedTime
'Next
'Next
'End With
With New_c 'RC5/RC6 based cdecl-Helper-call
Dim pArgs As Long, Args(0 To 1) As Long
pArgs = VarPtr(Args(0))
For K = 1 To TimesVal
For i = 1 To Imax
Args(0) = i
Args(1) = i * 2
QueryPerformanceCounter CPUv1
Ret = .cdeclCallDirect(retLong, ExcuteJavaScript_Ptr, pArgs, 8)
QueryPerformanceCounter CPUv2
CusedTime = (CPUv2 - CPUv1) / MsCpu
TimeSz(7) = TimeSz(7) + CusedTime
Next
Next
MethodName(7) = "RC5/6 cdeclcall"
End With
And the result I got (running the native-compiled *.exe) is this one:
https://www.vbforums.com/images/ieimages/2020/12/1.png
And as you can see from the native compiled results, the call-overheads differ from yours - and are all (unsurprisingly) -
roughly at the same level of about 13-26msec (averaging at about 20msec to perform the 0.5Mio calls).
The only significant outlier regarding the Overhead is (with 372msec) the DispCallFunc-based cdecl-call.
The COM-based calls (via Class-Methods) have to transport "2 additional Params" - and have therefore a timing "above 20msec"
(this includes the call via the RC5/6 cdecl helper, which also has to go through that COM-call-overhead - and is therefore a bit slower than the "trampoline").
That testing done - what I would like to see from you, is a real-world test-example (not a micro-benchmark) -
where you call into a cdecl-library (as e.g. the original sqlite3.dll binary from sqlite.org),
and then do "some real work" with that dll (e.g. the Excel-import/export scenario you mentioned).
Olaf
Re: hao to call Sqlite3.dll with cdecl?
Quote:
Originally Posted by
wqweto
You cannot "fix" this. The logic is broken.
When you JMP to DllFunAddr the function there wil RET to the original address of the caller so your ADD ESP, Xh will not be reached at all.
I already told you what needs to be done: shuffle the args so that a *new* return address is inserted on the stack, namely the address of your ADD ESP, Xh + RET thunk.
Shuffling args with REP MOVSB will be slower that PUSH-ing one more additional param as the original solution proposed by The Trick in the thread.
I know you'd love to micro-benchmark it with yet another flowed benchmark of yours. This
Code:
QueryPerformanceCounter CPUv1
ret = .CallFuncAddress(ExcuteJavaScript_Ptr, a, b)
QueryPerformanceCounter CPUv2
. . . is wrong on so many levels. You cannot benchmark like this as the performance counters are not precise enough. It's impossible to measure couple of instructions with QueryPerformanceCounter. This API takes a lot more that couple of instructions to execute and the mutlimedia timer it's using is not precise enough.
Suppose you have functions f and g. You have to benchmark a loop of million executions for f (A), then for g (B) and finally million executions of an empty loop (C) then compare A - C vs B - C.
cheers,
</wqw>
test :50*100000 times
VbAddRef--8.5441 MS
VbAdd--7.3409 MS
CallCdecl2--46.6595 MS ( more than ClassFriendAdd)
Com vTable--2998.326 MS
DispCallFunc--4087.915 MS
ClassAdd--119.4827 MS
ClassAddRef--110.8526 MS
ClassFriendAdd--12.643 MS
cCDECL.CLS--2100.1245 MS
Code:
QueryPerformanceCounter CPUv1
For K = 1 To KMAX
For i = 1 To Count
a = i
b = i * 2
ret = VbAdd(a, b)
Next
Next
QueryPerformanceCounter CPUv2
TimeSz(1) = (CPUv2 - CPUv1) / MsCpu
Re: hao to call Sqlite3.dll with cdecl?
address1 = GetProADDRESS(dll,"Add")
function MyAdd(byval a as long,byval b as long0
'put asm code for call address1
end function
Public Function CallCdecl2(ByVal Pfn As Long, ByVal Arg1 As Long, ByVal Arg2 As Long, Optional ByVal Spacer As Long) As Long
CallCdecl2 will fast than call MyAdd?
Re: hao to call Sqlite3.dll with cdecl?
RE:That testing done - what I would like to see from you, is a real-world test-example (not a micro-benchmark) -
where you call into a cdecl-library (as e.g. the original sqlite3.dll binary from sqlite.org),
and then do "some real work" with that dll (e.g. the Excel-import/export scenario you mentioned).
Olaf
==============
At present, I mainly test how to CDECL API call the most convenient and the fastest. Specific how to use SQLite, the interested person to test it. Perhaps the fastest way is to query once and then receive data from callback n times. Another way is to get table once, directly save all data to VB6 string array.
i want to study,CAN YOU GIve me vb6 sources of " RC5/6 cdecl "?thank you
1 Attachment(s)
Re: how to Fast Call cdecl api like sqlite3.dll?
Call Cdecl by VB Function
why Stack was trashed by 4 bytes?
Code:
Function VB_CdeclAPI_Sum(ByVal a As Long, ByVal b As Long) As Long
MsgBox 1
MsgBox 2
MsgBox 2
MsgBox 2
MsgBox 2
End Function
Sub FixCdecl(VbFunction As Long, CdeclApi As Long, args As Long)
'ESP堆栈不平衡 Stack was trashed by 4 bytes
Dim asm() As String, stub() As Byte
Dim i As Long, argSize As Long
argSize = args * 4
' 0: 58 pop eax
' 1: 89 84 24 XX XX XX XX mov dword ptr [esp+Xh],eax
push asm(), "58 89 84 24 " & lng2Hex(argSize + 0) '&H24848958
push asm(), "B8 " & lng2Hex(CdeclApi) 'B8 90807000 MOV EAX,708090
push asm(), "FF D0" 'FFD0 CALL EAX
push asm(), "83 C4 " & Hex(argSize + 0) '83 C4 XX add esp, XX 'cleanup args
'push asm(), "C2 10 00"
push asm(), "C3"
stub() = toBytes(Join(asm, " "))
Dim THUNK_SIZE As Long
THUNK_SIZE = UBound(stub) + 1
VirtualProtect2 VbFunction, THUNK_SIZE, PAGE_EXECUTE_READWRITE, 0 '更改函数地址所在页面属性
WriteProcessMemory2 -1, VbFunction, VarPtr(stub(0)), THUNK_SIZE, 0
'Vblegend.VirtualProtect VbFunction, THUNK_SIZE, PAGE_EXECUTE_READWRITE, 0 '更改函数地址所在页面属性
'Vblegend.WriteProcessMemory -1, VbFunction, stub(0), THUNK_SIZE, 0
End Sub
form1 code:
Code:
Dim startESP As Long, endEsp As Long
startESP = getESP
Dim h As Long, ret As Long
Dim CdeclApi As Long, lpfnAdd As Long, lpfnVoid As Long, lpfnSub As Long
h = LoadLibrary("cdecl.dll")
CdeclApi = GetProcAddress(h, "Add")
Dim a As Long, b As Long, c As Long
a = 44
b = 55
FixCdecl AddressOf VB_CdeclAPI_Sum, CdeclApi, 2
' FixCdecl AddressOf VB_CdeclAPI_Sum, CdeclApi, 8
startESP = getESP
c = VB_CdeclAPI_Sum(a, b)
endEsp = getESP
MsgBox "c=" & c
'ESP堆栈不平衡
MsgBox "Stack was trashed by " & (endEsp - startESP) & " bytes"