News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How To Export Struct From Dll ?

Started by devilhorse, March 13, 2010, 05:37:56 AM

Previous topic - Next topic

devilhorse

Does anyone have some basic advice on how to export a struct from a dll. I know how to do this in C+= but am having trouble in masm.  I have done many searches on Google but cannot find useful information on the required steps to follow. Can a struct be exported from a dll? Is the use of a def file necessary if the struct can be exported?

hutch--

devilhorse,

Its usually the case that if you want a structure full of data from and external function you must pass an empty structure to it so it can fill it with the data you require. I have seen functions designed where the data comes back to you as dynamic memory allocated in the external function but its slow in comparison to passing the structure first.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MichaelW

#2
The attachment is a working example. In the DEF file there may be some way to use DATA instead of the obsolete CONSTANT, but in the time I had to spend on it I could not find any way.

Importing into an Application

eschew obfuscation

devilhorse


jj2007

Here is another example showing two alternative methods: Use a global structure inside the DLL (A), or pass a pointer to a structure to the DLL (B).

The DLL:
include \masm32\include\masm32rt.inc

.data?
TheRect RECT <?> ; we use a global structure in the DLL for method B

.code
LibMain proc instance:DWORD, reason:DWORD, unused:DWORD
    mov eax, TRUE
    ret
LibMain endp

GetTheRectA proc pStruct ; $export
  invoke GetClientRect, rv(GetDesktopWindow), pStruct
  mov eax, pStruct
  ret
GetTheRectA endp

GetTheRectB proc ; $export
  mov eax, offset TheRect
  push eax
  push eax
  push rv(GetDesktopWindow)
  call GetClientRect
  pop eax ; aka offset TheRect
  ret
GetTheRectB endp

end LibMain


The calling code:
include \masm32\include\masm32rt.inc

.data?
hDll dd ?
rectCaller RECT <?>
pUseA dd ?
pUseB dd ?

.code
start:
mov hDll, rv(LoadLibrary, chr$("Struct_Dll")) ; rv is the retval macro ([url=\masm32\macros\macros.asm#"rv macro"]source[/url]), which returns eax
.if eax
mov pUseA, rv(GetProcAddress, hDll, chr$("GetTheRectA"))
.if eax
push offset rectCaller ; we use a global structure for method A
call pUseA
xchg ebx, eax ; move the pointer to the structure into a protected register
print "Desktop width and height, method A: "
print str$([ebx.RECT.right]), "/"
print str$([ebx.RECT.bottom]), 13, 10
.else
invoke MessageBox, 0, chr$("GetTheRectA not found"), 0, MB_OK
.endif
mov pUseB, rv(GetProcAddress, hDll, chr$("GetTheRectB"))
.if eax
call pUseB
print "Desktop width and height, method B: "
print str$([rectCaller.right]), "/"
print str$([rectCaller.bottom])
.else
invoke MessageBox, 0, chr$("GetTheRectB not found"), 0, MB_OK
.endif
invoke FreeLibrary, hDll
.else
invoke MessageBox, 0, chr$("DLL not found"), 0, MB_OK
.endif
exit

end start