ok i made a a dll, works but when i call it it does not return any values.my code is below
btw im calling this from vb



.Code

dllmain Proc xcompielr:DWORD, xdamn:DWORD, xwarning:DWORD
ret
dllmain EndP

Testspeed Proc Ftime1:DWORD, Ftime2:DWORD, FtimeDIFF:DWORD
Local Ticks1 :DWORD
Local Ticks2 :DWORD

Invoke GetTickCount
mov Ticks1, eax
mov eax, 00h

loop1:
inc eax
cmp eax, 00FFFFFFh
jne loop1

Invoke GetTickCount
mov Ticks2, eax
mov eax, Ticks1
mov Ftime1, eax
mov eax, Ticks2
mov Ftime2, eax
sub Ticks1, eax
mov eax, Ticks1
mov FtimeDIFF, eax
ret
Testspeed EndP
End dllmain

Posted on 2002-03-15 21:33:03 by Qages
When you wish to pass parameters to a DLL as , you need pass then ByRef, as opposed to ByVal.

The difference is ByVal passes the actual runtime value of a variable, and ByRef passes the address where that value is stored.

Now, once control returns to VB, VB will look at the address where it stores a variable. And that address is what you need change.

Your code would thus look like so:



Testspeed Proc pFtime1:DWORD, pFtime2:DWORD, pFtimeDIFF:DWORD
Local Ticks1 :DWORD
Local Ticks2 :DWORD

Invoke GetTickCount
mov Ticks1, eax
mov eax, 00h

loop1:
inc eax
cmp eax, 00FFFFFFh
jne loop1

Invoke GetTickCount
mov Ticks2 , eax
mov ecx, pTicks2 ; gets the ADDRESS of Ftime2
mov [ecx], eax ; saves GetTickCount to Ftime2
mov eax, Ticks1
mov ecx, pFtime1 ; gets the ADDRESS of Ftime1
mov [ecx], eax ; saves GetTickCount to Ftime1
mov eax, Ticks2
sub Ticks1, eax
mov eax, Ticks1
mov ecx, pFtimeDIFF ; gets the ADDRESS of FtimeDIFF
mov [ecx], eax ; saves GetTickCount to FtimeDIFF
ret
Testspeed EndP


You also must define the dll proto in VB to pass the values ByRef.

Technically, you are calling a Subroutine here, not a function. The difference is a function will return an extra value in eax. VBB then uses that value and assigns it to whatever you assigned it to (with the equals sign).

Subs don't return a value, though in later versions of VB it seems the definitions os Sub and Function have converged to mean the same thing.
Posted on 2002-03-15 23:13:10 by Ernie
ok thx i did not know you had to get its address, im used to vb where every thing is done for you :)
Posted on 2002-03-15 23:37:43 by Qages
Qages,

In your DLLmain, use this

mov eax, 1
ret

If you return zero, the DLL assumes an error and will not load.

Regards,

hutch@movsd.com
Posted on 2002-03-15 23:49:52 by hutch--
i do not use the dllmain as a sub, its just like that bec it(compiler) was sayin i needed 12 bytes of args, i have it working
im just calling Testspeed
results:
assembly is 21.47~8 times faster then vb!!!!!!
90 ms to exectue in asm
1993 ms in vb


Q; is there any way to remove these 10 byte dup (0)'s there are in my exe it shows me when i disasemble it in w32dasm?
Posted on 2002-03-15 23:57:42 by Qages
Qages,

If you are going to build successful DLLs to call with other languages, do it according to the documentation. Look up "DllEntryPoint" in win32.hlp for more information but at the minimum you should return TRUE (1) in the LibMain/DllMain.

It is normally returned from the "DLL_PROCESS_ATTACH" part when the "fdwReason" parameter is evaluated.

You NEVER call the LibMain/DllMain, the operating system loader does this when it first loads the DLL. The reason for the option at startup is if there is a failure, the load will abort.

Regards,

hutch@movsd.com
Posted on 2002-03-16 01:45:15 by hutch--
Quages,
what ever is in the eax register when your function exits is what is returned to your vb function.

It is good that you have posted some code, but we still only have one side of the story (so to speak). You should also post your vb code, specifically your Testspeed function declare, and the segment of code that calls Testspeed.

As for the "10 byte dup (0)'s", you should post the .data section of your code, there has to be something in there causing it.
Posted on 2002-03-16 03:37:14 by sluggy
i dont have a .data section yet(not using it at the momemnt.) is that why its bloating my exe?
i am returning 1 in eax in both of my procs.
i will post all of my code



.386
.model flat, stdcall
option casemap :none

Include ..\masm32\Include\windows.inc
Include ..\masm32\Include\user32.inc
Include ..\masm32\Include\kernel32.inc

IncludeLib ..\masm32\lib\user32.lib
IncludeLib ..\masm32\lib\kernel32.lib
; #########################################################################
.Code

dllmain Proc xcompielr:DWORD, xdamn:DWORD, xwarning:DWORD
mov eax, 01h
ret
dllmain EndP

Testspeed Proc pFtime1:DWORD, pFtime2:DWORD, pFtimeDIFF:DWORD, pLoopTimes:DWORD
Local Ticks1 :DWORD
Local Ticks2 :DWORD

Invoke GetTickCount
mov Ticks1, eax
mov eax, 00h

loop1:
inc eax
cmp eax, pLoopTimes
jne loop1

Invoke GetTickCount
mov ecx, pFtime2 ; gets the ADDRESS of Ftime2
mov [ecx], eax ; saves GetTickCount to Ftime2
sub eax, Ticks1
mov ecx, pFtimeDIFF ; gets the ADDRESS of FtimeDIFF
mov [ecx], eax ; saves GetTickCount to FtimeDIFF
mov eax, Ticks1
mov ecx, pFtime1 ; gets the ADDRESS of Ftime1
mov [ecx], eax ; saves GetTickCount to Ftime1
mov eax, 01h
ret
Testspeed EndP
End dllmain



vb


Private Declare Sub test3bytes Lib "Firstdll.dll" Alias "Testspeed" (ByRef Xtimebeg As Long, ByRef Xtimeend As Long, ByRef Xtimediff As Long, ByVal Xamt As Long)
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub Main()
Dim val1 As Long, val2 As Long, val3 As Long, time1 As Long, time2 As Long, i As Long, b As Long
MsgBox "this test is " & Format(&H7FFFFFFF, "###,###") & " times"
Call test3bytes(val1, val2, val3, &H7FFFFFEF)
MsgBox val3 & " milliseconds to execute a loop adding 1 by one " & &H7FFFFFEF & " times iN ASM!! ~ dont worry if it is slow to show the next box heh"
time1 = GetTickCount
For i = 1 To &H7FFFFFEF
b = b + 1
Next i
time2 = GetTickCount
MsgBox CStr(time2 - time1) & " milliseconds to execute a loop adding 1 by one " & &H7FFFFFEF & " times iN VB!!"
MsgBox "asm times faster " & CStr((time2 - time1) / val3) & " than vb"
End Sub


Posted on 2002-03-16 12:40:50 by Qages
Your VB declare looks alright. I will assume that you have correctly exported the TestSpeed in your def file.

In your asm code, this is what i would suggest:

change this:
   cmp eax, pLoopTimes
to this:
   dec pLoopTimes
It is not a major change, i think it is just slightly more efficient than the cmp.

And change all instances of this:
   mov [ecx], eax 
to this:
   mov dword ptr [ecx], eax 
This is just to make sure you are using the target of the pointer, not the just the register containing the pointer (IIRC putting brackets around a register in MASM is the same as just using the register without brackets, while in TASM it signifies you want to use that register as a pointer).

I will chuck your code into my IDEs later today, see if anything else comes to my attention.
Posted on 2002-03-16 21:08:44 by sluggy