What do you need to do to be able to use DLL procs in Assembly DLLs in HLLs like VB?

For example, let's say, in my assembly DLL, I have:



_ByteAPI_String_dwStringLength PROTO hString:DWORD

.code

_ByteAPI_String_dwStringLength proc hString:DWORD
;Make sure the handle is valid
mov eax,hString
test eax,NULL
je At_Error

;Use registers instead of memory for additional speed
ASSUME eax: ptr BYTE
mov eax,hString ;The address of the string, incremented by 8 bits [length of a byte] each loop
xor ebx,ebx ;The string length counter
xor cx,cx

Loop_GetLength:
mov cl,[eax] ;Add the current byte to CL
inc eax ;Add 1 byte to the address position
test cl,ch ;Compare to a null character, 0h, which signals the end of a string. This is stored in ch so it is faster than immed
jne Loop_GetLength
mov ebx,hString
inc ebx
sub eax,ebx
ret

At_Error:
mov eax,-1 ;If a failure occured, simply return -1
ret
_ByteAPI_String_dwStringLength endp


Now, in my VB program I have:



Namespace ByteAPI
Public Class [String]
Public Declare Unicode Sub dwStringLength Lib "ByteAPI.dll" Alias "_ByteAPI_String_dwStringLength" (ByVal hString As IntPtr)
End Class
End Namespace


It says it cannot find the entrypoint "_ByteAPI_String_dwStringLength" in ByteAPI.dll. Despite that the functions are defined as such in that DLL.

What am I doing wrong?
Posted on 2004-11-20 17:20:30 by לח&am
Afternoon, ??&am.

As you're declaring the function as public, I assume that this declaration is inside the bas file.

See if the following works:
Public Declare Function dwStringLength Lib "ByteAPI" Alias _ 

"_ByteAPI_String_dwStringLength" (ByVal hString As IntPtr) As Long


Cheers,
Scronty
Posted on 2004-11-20 18:07:27 by Scronty
I just tested that now. It still gives a run-time error.

It must be in the DLL itself. I think that the dll doesn't have the function names, but instead ordinals, because of the way I assembled it.

Edit: Appearantly you need to add /export:subname for each and every sub to the linker. I read this in a FAQ, that you add it to the batch file you would run to compile it. Is there an easier way? Doing this for 30 subs in a linker hardly seems fair.
Posted on 2004-11-20 18:17:42 by לח&am
Default linker option ought to be inserting the subnames by name.

You may want to use DUMPBIN (does it come with MASM32?) with the /EXPORTS option to see what the true name is. The true name is what you put in the Alias clause.
Posted on 2004-11-21 02:34:17 by tenkey
Afternoon, "??&am".

Are you using a *.def file for the linking?
i.e.
ByteAPI.asm has your proc:
e.g.
blah blah

...
_ByteAPI_String_dwStringLength proc hString:DWORD
...
blah blah


ByteAPI.def has the exported functions:
e.g.
LIBRARY ByteAPI

EXPORTS
_ByteAPI_String_dwStringLength


Plus you build your Dll file with a *.bat file which has something like:
\masm32\bin\ml /c /coff /Cp ByteAPI.ASM

\masm32\bin\Link /SECTION:.bss,S /DLL /DEF:ByteAPI.def /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib ByteAPI.obj


Cheers,
Scronty
Posted on 2004-11-21 04:32:03 by Scronty
Thank you!

This forum is really helping me in the basics. Maybe one day I can contribute.
Posted on 2004-11-21 13:47:47 by לח&am