The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: jj2007 on December 03, 2007, 04:58:11 PM

Title: DLL exports without .DEF file
Post by: jj2007 on December 03, 2007, 04:58:11 PM
I am building a number of DLLs, and would like, out of laziness, to get rid of the .def file:

LIBRARY MyfavouriteDll
EXPORTS TextExp
EXPORTS FunStuff

Apparently, it is possible to do that by using this syntax:

TestExp proc EXPORT Arg1:DWORD, Arg2:DWORD, Arg3:WORD ; results in _TestEx@12
xor eax,eax ; whatever
add esp,12
ret
TestExp endp

The keyword EXPORT after proc tells the linker to export the name of the function.
LIBRARY is not needed, the linker uses the name of the source file, i.e. myfile.asm becomes myfile.dll, which is the desired behaviour.

So far, so fine. But now the problem: In the dll, the name of the exported function TestExp becomes

_TestExp@12

i.e. leading understroke, and @12 indicating the 4*3 bytes of arguments. This name "_TestExp@12" can safely be called using

invoke GetProcAddress, hDll, chr$("_TestExp@12")

That is certainly very informative, but it's ugly. I don't like leading understrokes, and will never understand why Microsoft indulges in using even two or three of them - to prevent ordinary people from understanding their code, probably.

I've checked the documentation and could not find anything explaining this particular behaviour. Can somebody solve the mystery, and point me to a better option? Please don't tell me to use a .def file, as I hate seeing my hard disk cluttered with little files here and there...

Thanxalot :bg
Title: Re: DLL exports without .DEF file
Post by: evlncrn8 on December 03, 2007, 05:08:50 PM
think you need to put in the calling convention into it too... __stdcall if i remember right
Title: Re: DLL exports without .DEF file
Post by: Vortex on December 03, 2007, 07:14:20 PM
Hi jj2007,

Mainly, name mangling like _MessageBoxA@16 is a notation specific to the C++ language informing the linker about the version of the overloaded functions.

You can use Pelle's linker Polink to solve the problem :

\masm32\bin\polink /SUBSYSTEM:CONSOLE /DLL @Exports.txt ConsFuncs.obj

Exports.txt :

/EXPORT:locate /EXPORT:StdOut /EXPORT:ClearScreen /EXPORT:StrLen

Exports.txt is a response file declaring the exported functions.

[attachment deleted by admin]
Title: Re: DLL exports without .DEF file
Post by: Vortex on December 03, 2007, 08:31:22 PM
To simplify the task, I patched the object file to undecorate the symbols in the .ndrectve section. ( directive section )
Check the image PatchObjfile.png included in the attachment to see how the method is applied.

[attachment deleted by admin]
Title: Re: DLL exports without .DEF file
Post by: jj2007 on December 04, 2007, 12:00:43 AM
Hmmmm.... :dazzled:
Maybe I have not fully grasped the concept of "simplifying" - but thanks anyway for showing me the way, Vortex  :bg
So I could not resist the temptation to write a little wrapper. The attached archive has path names - extract to the root of your masm drive (mine is D: ) using folder names.
D:\masm32\VxDemo\ConsFuncs.asm is only slightly modified - look for RUN=demo
D:\masm32\Make_DLL.bat contains my settings - no need to change anything, it will work with other sources, too.
D:\masm32\MAKE_DLL.EXE is the wrapper; create a shortcut, move it to D:\masm32\VxDemo, and drag ConsFuncs.asm over the shortcut.
Strangely enough, ConsFuncs.dll seems to be shorter than in your example; I had to use the standard linker since polink complained about unresolved external symbols _stdout etc.
If the wrapper finds at the end of one of the xxx proc export lines a RUN=whateverfile.exe, the make_dll.bat will execute this file if assembling and linking was ok.

EDIT: Reading helps sometimes. I now realise that Vortex "calls" the DLL by linking it into the asm code, a technique that I have never used and will not be able to grasp at 3:00 in the morning. But I got a GetProcAddress example running - attached ConsFuncs_demo2.zip
What it essentially does is to parse any lines in the asm source containing the string "proc":
- extracts the name of the proc if the EXPORT keyword comes after "proc"
- checks the proc line for an UPPERCASE RUN=MyDemo.exe "with arguments"
- write the EXPORTS to a local TmpDllEx.def definition file, nicely formatted
- and runs the dll_temp.bat

I also changed the wrapper slightly; not it D:\masm32\Make_DLL.bat as a template, replaces the %1 etc args and writes it to disk as Dll_temp.bat, so that the user can see what exactly happens there.


[attachment deleted by admin]
Title: Re: DLL exports without .DEF file
Post by: zooba on December 04, 2007, 05:46:54 AM
In one of my projects I wanted to do exactly the same thing. I wrote a substitute PROLOGUE macro that echos the name of every procedure (except DLLMain) to stdout when you build it, wrapped up inside an IFDEF.


IFDEF NAMESOUT
    OPTION PROLOGUE:MyPro
   
    MyPro MACRO procname, flags, argbytes, localbytes, reglist, userparms:VARARG
        IFDIF <procname>,<DLLMain>
            ECHO procname
        ENDIF
        EXITM <1>
    ENDM
ENDIF


I then built using a batch file specific to that project, but the relevant part is here (gle is the project name, and I'm using a response file because I was building with a version that didn't support wildcards on the command line, version 7? I can't remember now):


dir /b *.asm > gle.rsp
\masm32\bin\ml /c /coff /nologo /DNAMESOUT @gle.rsp > functions.list

echo LIBRARY gle > gle.def
echo EXPORTS    >> gle.def
sort < functions.list | find /V " Assembling:" >> gle.def
del functions.list


After this you'll need to build a second time without the /DNAMESOUT setting and then link with the .def file generated.

It's a bit of work to set up, but makes things reasonably simple once you're going.

Cheers,

Zooba :U
Title: Re: DLL exports without .DEF file
Post by: donkey on December 04, 2007, 09:46:14 AM
I don't know, it seems to me there is more work to not having a DEF file than the other way around, laziness only pays off if there is less work. The laziest way to do it is to use RadASM, right click the procedure name in the code properties window and select "Add Export" ;)

Another easy way for GoAsm users is like this...

EXPORT MyProc FRAME lParam
    xor eax,eax
    ret
ENDF


GoAsm does not require a DEF file or any special setup, though I generally use a DEF file anyway to make my DLLs more easily translated to MASM.

Donkey
Title: Re: DLL exports without .DEF file
Post by: Mark Jones on December 04, 2007, 02:20:10 PM
Sorry for going a little off-topic but I'm liking GoAsm more and more. Donkey's libraries has made it even more useable (thanks!), however I miss the conditionals of MASM (and tried to make a GoAsm SWITCH/CASE macro to failure) but am thinking GoAsm might still be the best alternative assembler out there. I just love being able to do:


    invoke MessageBox,0,<'Hello World!',13,10,'This is a "nice" feature!',0>,"MessageBox",MB_OK
Title: Re: DLL exports without .DEF file
Post by: Vortex on December 04, 2007, 06:07:00 PM
QuoteI now realise that Vortex "calls" the DLL by linking it into the asm code, a technique that I have never used and will not be able to grasp at 3:00 in the morning.

jj2007,

Believe, you are using the technique everyday :
This one,
includelib  \masm32\lib\kernel32.lib
and this one :
includelib  ConsFuncs.lib
have no any difference in techical terms. This method is called Load-Time Dynamic Linking.
Calling functions with LoadLibrary refers to the Run-Time Dynamic Linking method.
Title: Re: DLL exports without .DEF file
Post by: jj2007 on December 04, 2007, 06:26:16 PM
Quote from: donkey on December 04, 2007, 09:46:14 AM
I don't know, it seems to me there is more work to not having a DEF file than the other way around, laziness only pays off if there is less work
I am fighting hard to get the laziest version ever. See attachment - now for DLLs, console and Windows apps.

EDIT: Just discovered an odd behaviour: I always thought batch files worked synchronously, i.e. prog2 waits until prog1 has finished the job. This seems not to be the case: To make this work, insert a PAUSE in StartMe.bat between the two calls to MAKE_ASM.EXE - otherwise A simple dll.asm will assemble to an exe, and the second proggie fails with an error message. Don't ask me why...
In both A simple dll.asm and Demo with GetProcAddress.asm, there is a section in the format

; OPT_RES rsrc.obj ; use if needed
; OPT_SUSY CONSOLE ; Subsystem; default is WINDOWS, use CONSOLE if needed
; OPT_CLEANLST 1 ;lst file is not needed, right?

Make_asm.exe checks for the OPT_ and decides to write an environment variable of the form

set oRes=rsrc.obj
set oSusy=CONSOLE
set oCleanlst=1

to the temporary batch file Dll_temp.bat, which is based on the freely configurable \masm32\Make_asm.txt
So you can define all necessary options directly in the source file. Furthermore, Make_asm.exe checks for <name> proc EXPORT and writes these names to TmpDllEx.def - hence no definition file needed. The system is pretty flexible, and fast, too. Main advantage is that all options can be defined directly in the ASM source, and the batch file behaviour can be tailored to the source.

[attachment deleted by admin]
Title: Re: DLL exports without .DEF file
Post by: zooba on December 05, 2007, 06:58:34 AM
Looks quite similar to my own build tool (http://web.aanet.com.au/zooba/build.zip). :bg

It doesn't actually do exports automatically, but the source is included (you'll need ASM Runtime (http://web.aanet.com.au/zooba/ASMRT.zip) to build it) and it should be easy (relatively) to add it in. I was just reading the source, which I haven't look at in over a year, and it still makes sense, so it must be pretty clear  :toothy

</shameless self promotion>

Cheers,

Zooba :U
Title: Re: DLL exports without .DEF file
Post by: jj2007 on December 05, 2007, 08:16:53 AM
Quote from: zooba on December 05, 2007, 06:58:34 AM
</shameless self promotion>
I love competition  :U
Title: AsmBuild - the ultimate tool for lazy coders like me
Post by: jj2007 on December 05, 2007, 11:03:32 PM
I was restlessly working on my little tool, and decided to make it even more flexible and easy yo use.
With the new version, you can build a dll, GUI or console app directly from the asm source, without definition files, and without a specific makefile. See yourself...
Note this took longer than expected because of the extremely crappy behaviour and documentation of Windows batch files, namely the START, CALL and CMD functions. More in the README.TXT file.
EDIT: Corrected a harmless little bug - please take the second zip.

[attachment deleted by admin]
Title: Re: DLL exports without .DEF file
Post by: jj2007 on December 07, 2007, 10:28:46 AM
Quote from: zooba on December 04, 2007, 05:46:54 AM
In one of my projects I wanted to do exactly the same thing.
...

dir /b *.asm > gle.rsp
\masm32\bin\ml /c /coff /nologo /DNAMESOUT @gle.rsp > functions.list

echo LIBRARY gle > gle.def
echo EXPORTS    >> gle.def
sort < functions.list | find /V " Assembling:" >> gle.def
del functions.list

Hmmm... I tried this one, but 1. MASM chokes on filenames with spaces, and 2. even without spaces, I get an empty list back using the batch below:

dir /b A_S*.asm > A_simple_dll.rsp
\masm32\bin\ml /c /coff /nologo /DNAMESOUT @A_simple_dll.rsp > functions.list

echo LIBRARY A_simple_dll > A_simple_dll.def
echo EXPORTS    >> A_simple_dll.def
sort < functions.list | find /V " Assembling:" >> A_simple_dll.def
rem del functions.list
pause

functions.list contains a single line:  Assembling: A_simple_dll.asm, same for A_simple_dll.rsp
A_simple_dll.asm has marked the exports like this:

ClearScreen PROC EXPORT    ; from masm32.lib

In the meantime, AsmBuild has learnt to automatically recognise dll, console and win apps, to include resource files, and to tolerate long path and file names with spaces. I tested it on many of the \Masm32\examples, and it works as it should, i.e. opening the *.asm with \Masm32\asmbuild\ASMBUILD.EXE builds the exe or dll without an extra build.bat or *.def file etc.

[attachment deleted by admin]
Title: Re: DLL exports without .DEF file
Post by: zooba on December 08, 2007, 01:01:35 AM
jj2007,

Did you include the alternate prologue macro? It needs both of them to work.


IFDEF NAMESOUT
    OPTION PROLOGUE:MyPro
   
    MyPro MACRO procname, flags, argbytes, localbytes, reglist, userparms:VARARG
        IFDIF <procname>,<DLLMain>
            ECHO procname
        ENDIF
        EXITM <1>
    ENDM
ENDIF


Of course, building it into the build system is much cleaner :bg

Cheers,

Zooba :U
Title: Re: DLL exports without .DEF file
Post by: vid on December 08, 2007, 01:32:20 AM
Quote from: Vortex on December 03, 2007, 07:14:20 PM
You can use Pelle's linker Polink to solve the problem :

\masm32\bin\polink /SUBSYSTEM:CONSOLE /DLL @Exports.txt ConsFuncs.obj

Exports.txt :

/EXPORT:locate /EXPORT:StdOut /EXPORT:ClearScreen /EXPORT:StrLen

Exports.txt is a response file declaring the exported functions.
why just PoLink? MS link can do exactly the same.
Title: Re: DLL exports without .DEF file
Post by: jj2007 on December 08, 2007, 08:12:07 AM
Quote from: vid on December 08, 2007, 01:32:20 AM
Quote from: Vortex on December 03, 2007, 07:14:20 PM
You can use Pelle's linker Polink to solve the problem :
why just PoLink? MS link can do exactly the same.
Indeed, although in some instances it might be a bit more efficient.
But that is not the point. What I am trying to produce is a tool that allows to double-click on an ASM file sitting lonely in a folder, maybe together with a rsrc.rc and a readme.txt but no more. Currently I am testing this on the icztutes and the examples, by moving all "unnecessary" files (makeit.bat etc.) into an "old" folder and then double-clicking on the *.asm (the extension is now associated with \masm32\AsmBuild\AsmBuild.exe). It seems to work...

[attachment deleted by admin]