I am writing a dll in masm32 for use with vb. how do i return a string? I am still learning masm32, please help me. The proc works fine in masm32 but returns nothing in vb or crashes.
Thanks.
Code:
GetNewTempFile proc strPrefix :LPCSTR, strNewFileName:LPSTR
local buf[256]:dword
local b[256]:dword
invoke GetTempPath,256,addr buf
invoke GetTempFileName,addr buf,strPrefix,0,addr b
invoke lstrlen,addr strNewFileName
ret
GetNewTempFile EndP
Just take a look at the default __stdcall specification - which is also used by VB - from MSDN.: here.
This is basic knowledge of how to write a function. But one information is missing in MSDN: Return values are given back to the caller via the EAX register. So put the pointer to your string into the EAX register. And beware: Never return a local variable pointer (which is allocated on the stack) back to the caller, since the stack get's cleaned up, the pointer will be invalid after the "ret" instruction. So use a dynamic allocator to allocate the string.
Thanks for your response NoHero. I wish to return the string in parameter 2. How do i go about it? I am still stuck, could you give a simple example please? Thank you.
INVOKE SysAllocStringLen, offset lbBuffer, quantity
The offset lbuffer is used when you have a ready string loaded on a .data variable.
If you want to start a new string, pass 0 or NULL for lbBuffer
Ex: Testing a 4 CHARS unicode string , each char = 2 bytes or 1 word:
INVOKE SysAllocStringLen, 0, 4
.IF eax != 0
mov word ptr [eax], 'a' ;load a first char
mov word ptr [eax+2], 'b' ;second char
mov word ptr [eax+4], 'c' ;third char
mov word ptr [eax+6], 'd' ;third char
.ENDIF
ret ; eax has the pointer.
Ex: Testing a 4 CHARS ANSI string , each char = 1 bytes:
INVOKE SysAllocStringLen, 0, 2 ; <-- half as we use only 1 byte per char:
.IF eax != 0
mov BYTE ptr [eax], 'a' ;load a first char
mov BYTEptr [eax+1], 'b' ;second char
mov BYTEptr [eax+2], 'c' ;third char
mov BYTEptr [eax+3], 'd' ;third char
.ENDIF
ret
; eax has the pointer.
In the Vb code you declare the function normally, with String return type.
No need to pass a string reference nor size. SysAllocStringLen does all for you
INVOKE SysAllocStringLen, offset lbBuffer, quantity
The offset lbuffer is used when you have a ready string loaded on a .data variable.
If you want to start a new string, pass 0 or NULL for lbBuffer
Ex: Testing a 4 CHARS unicode string , each char = 2 bytes or 1 word:
INVOKE SysAllocStringLen, 0, 4
.IF eax != 0
mov word ptr [eax], 'a' ;load a first char
mov word ptr [eax+2], 'b' ;second char
mov word ptr [eax+4], 'c' ;third char
mov word ptr [eax+6], 'd' ;third char
.ENDIF
ret ; eax has the pointer.
Ex: Testing a 4 CHARS ANSI string , each char = 1 bytes:
INVOKE SysAllocStringLen, 0, 2 ; <-- half as we use only 1 byte per char:
.IF eax != 0
mov BYTE ptr [eax], 'a' ;load a first char
mov BYTE ptr [eax+1], 'b' ;second char
mov BYTE ptr [eax+2], 'c' ;third char
mov BYTE ptr [eax+3], 'd' ;third char
.ENDIF
ret
; eax has the pointer.
In the Vb code you declare the function normally, with String return type.
To return a string, there is NO need to pass a string reference nor size.
Using SysAllocStringLen, it does all for you, I have DLL functions that return string working FINE in VB. They were made on MASM32
You're right that VB passes and returns strings as BSTR (unless they're passed as a ByVal parameter, IIRC). However, I hope that Saching22 already solved his problem sometime during the last seven years...
Bookmarks