The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: devilhorse on March 13, 2010, 05:37:56 AM

Title: How To Export Struct From Dll ?
Post by: devilhorse on March 13, 2010, 05:37:56 AM
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?
Title: Re: How To Export Struct From Dll ?
Post by: hutch-- on March 13, 2010, 08:11:08 AM
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.
Title: Re: How To Export Struct From Dll ?
Post by: MichaelW on March 13, 2010, 10:54:24 AM
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 (http://msdn.microsoft.com/en-us/library/kh1zw7z7(v=VS.80).aspx)

Title: Re: How To Export Struct From Dll ?
Post by: devilhorse on March 13, 2010, 05:23:51 PM
Thank You for your fast reply.
Title: Re: How To Export Struct From Dll ?
Post by: jj2007 on March 13, 2010, 06:29:20 PM
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