I'd like to learn calling functions from masm dll's in vb6.
I tried and failed, so help me please:

-My masm dll code

.model flat, stdcall                 
option casemap :none
include \masm32\include\windows.inc       
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm
include \masm32\include\user32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

AppName    BYTE  "eugeneRandomizer DLL ", 0
LoadMsg      BYTE "The eugeneRandomizer  DLL is loaded. Good luck to you in whatever you are doing!", 0

UnloadMsg BYTE "The eugeneRandomizer is unloaded", 0

ThreadCreated BYTE "A thread is created in this process", 0
ThreadDestroyed BYTE "A thread is destroyed in this process", 0
offset_TS DWORD 0
RCounter DWORD      0


DllEntry PROC hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
mov  eax,TRUE
    DllEntry ENDP

    eugeneRandomizer PROC arg_mod :DWORD, resalt:DWORD
mov offset_TS, offset TS
    push offset_TS
    call GetLocalTime
          mov edi, dword ptr TS.wHour
          add edi, dword ptr TS.wSecond
          add edi, dword ptr TS.wMilliseconds
          sar edi, 4
          add edi, dword ptr RCounter
              inc RCounter 
          .while (edi >= arg_mod)
          sub edi, arg_mod
mov resalt, edi
    eugeneRandomizer ENDP
END  DllEntry

-My DEF File

LIBRARY eugeneRandom
EXPORTS eugeneRandomizer

-My vb code

Private Declare Function eugeneRandomizer Lib "D:\VB2\Projects\VB+ASM\eugeneRandom.dll" (ByVal arg_mod As Integer, ByVal resalt As Integer)

Private Sub Command1_Click()
Dim amod, res As Integer
amod = CInt(Text2)
res = CInt(Text3)
eugeneRandomizer amod, res
Text1 = res
End Sub

Please? i would look forward to your help, and especialy working example to learn by,

Posted on 2009-02-11 08:11:24 by Kydja
By the way, when i tried BASIC calling convention i couldn't built a dll at all!!
-Here is my bath file also
@echo off
\masm32\bin\ml /c /coff /Cp eugeneRandomizer.asm
\masm32\bin\link /DLL /DEF:eugeneRandomizer.def /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib eugeneRandomizer.obj
Posted on 2009-02-11 10:37:26 by Kydja
Shouldn't you add
Private Declare Function eugeneRandomizer Lib "D:\VB2\Projects\VB+ASM\eugeneRandom.dll" (ByVal arg_mod As Integer, ByVal resalt As Integer) As Integer
It's declared as a function, so needs a return-value type.

Your asm procs should be in STDCALL convention - which is the default with masm.
Posted on 2009-02-11 11:35:47 by Ultrano
Sorry, i was in a hurry. Of course, i returned integer, but it didn't helped me much.
Now i use Sub insted, and my dll function is parameterless(it just do a message box with hello world) but problem is the same...
Thank you
Posted on 2009-02-11 11:48:42 by Kydja
1) (unlikely) With Depends.exe or a hex-editor verify that in the DLL your exported proc is really called "eugeneRandomizer"  and not "_eugeneRandomizer" or "_eugeneRandomizer@8"
2) (very likely) preserve EBX, ESI, EDI.  VisualBasic might be copying ESP to one of these registers, and then after "ret" expect i.e EDI==ESP. This way it could be doing the checking of calling-convention (whether the stack remains balanced)
3) (unlikely) maybe ' Lib "eugeneRandom" '        instead of 'Lib "D:\....om.dll" ' could help
Posted on 2009-02-11 11:59:47 by Ultrano
Oh, ... instead of "As Integer", use "As Long"
VB integer is 16-bit.
Posted on 2009-02-11 12:02:01 by Ultrano
Thanks a lot,
I tried 1 and 2 option, with equal idleness, and now i am using dll with no parameters at all. Considering option #2, i ought to save registers in exported proc? or in dll entry point?
Couse now my dll looks like this:
.model flat,STDCALL               
option casemap :none
include \masm32\include\windows.inc       
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm
include \masm32\include\user32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
MsgCaption      db "Iczelion's tutorial no.2",0
MsgBoxText      db "Win32 Assembly is Great! But not working in VB6...",0

    DllEntry PROC hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
mov  eax,1
    DllEntry ENDP

    eugeneRandom PROC
invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
invoke ExitProcess,NULL
    eugeneRandom ENDP
END  DllEntry
Posted on 2009-02-11 12:07:29 by Kydja
I have no further ideas. Never dealt with vb<->dll interfacing. I've seen there are many examples here and on the net, try to follow them.
Posted on 2009-02-11 13:13:12 by Ultrano
Be so kind to point them to me.
Posted on 2009-02-11 13:56:57 by Kydja
You seem to be declaring "eugeneRandomizer" as a function but calling it as a sub in your VB code.

Try "Private Declare Sub eugeneRandomizer  ..."
Posted on 2009-02-11 20:13:41 by Wayne
Check THIS link out.
Posted on 2009-02-12 06:19:01 by XCHG
Thanks alot. I compiled the source code dll with MessageBox api and it works fine. But i could not find out what i was doing wrong...
Thank you very much guys for your readiness to help!
Posted on 2009-02-12 08:48:43 by Kydja
You must send the pointer of the resalt. Declare like this "ByRef resalt As Long".

Either you call the function "eugeneRandomizer amod, res" or "eugeneRandomizer amod, ByRef res". I don't exactly remember how to do it. I think it's the first alternative.

Posted on 2009-02-13 06:36:05 by minor28
Hi Kydja,

is this problem alredy solved or not yet? By the way, i have your code changed.
eugeneRandomizer PROC arg_mod :DWORD
invoke GetLocalTime,addr TS
mov eax, TS.wHour
add eax, TS.wSecond
add eax, TS.wMilliseconds
sar eax, 4
add eax, dword ptr RCounter
inc RCounter
.while (eax >= arg_mod)
sub eax, arg_mod
eugeneRandomizer ENDP

I got changed the register to EAX, that allows an easy way for the result. You can declare this Function in VB with return value.
Private Declare Function eugeneRandomizer Lib "eugeneRandom.dll" (ByVal arg_mod As Long) As Long

I hope that i can help you.
Posted on 2009-03-16 16:36:51 by Obivan