From: ian AT cygnus DOT com Subject: Re: Apologies 20 Feb 1998 20:25:52 -0800 Message-ID: <199802210004.TAA02360.cygnus.gnu-win32@tweedledumb.cygnus.com> References: To: root AT jacob DOT remcomp DOT fr Cc: gnu-win32 AT cygnus DOT com, noer AT cygnus DOT com > Every week there is somebody that points that the example in the cygnus > page copied verbatim will not work. What makes me mad, is that either the > example DOES work, and then you put it in the FAQ (or better in the page > itself) HOW TO MAKE IT WORK, or either it DOESN'T, then you take that > page away! But I am getting mad again. This is what I do to create a DLL with correct relocation information. This example is taken from the Tcl Makefile which will be included with the b19 release. Geoff, perhaps you could include something like this in the FAQ. IMPORTANT NOTE: I have not tested this with b18. I don't even have b18 loaded. I have only tested it with the upcoming b19 release. You must execute the following sequence of five commands, in this order: $(LD) -s --base-file BASEFILE --dll -o DLLNAME OBJS LIBS -e ENTRY $(DLLTOOL) --as=$(AS) --dllname DLLNAME --def DEFFILE --base-file BASEFILE --output-exp EXPFILE $(LD) -s --base-file BASEFILE EXPFILE -dll -o DLLNAME OBJS LIBS -e ENTRY $(DLLTOOL) --as=$(AS) --dllname DLLNAME --def DEFFILE --base-file BASEFILE --output-exp EXPFILE $(LD) EXPFILE --dll -o DLLNAME OBJS LIBS -e ENTRY $(LD) is the linker, ld. $(DLLTOOL) is dlltool. $(AS) is the assembler, as. DLLNAME is the name of the DLL you want to create, e.g., tcl80.dll. OBJS is the list of object files you want to put into the DLL. LIBS is the list of libraries you want to link the DLL against. For example, you may or may not want -lcygwin. You may want -lkernel32. Tcl links against -lcygwin -ladvapi32 -luser32 -lgdi32 -lcomdlg32 -lkernel32. DEFFILE is the name of your definitions file. A simple DEFFILE would consist of ``EXPORTS'' followed by a list of all symbols which should be exported from the DLL. Each symbol should be on a line by itself. Other programs will only be able to access the listed symbols. BASEFILE is a temporary file that is used during this five stage process, e.g., tcl.base. EXPFILE is another temporary file, e.g., tcl.exp. ENTRY is the name of the function which you want to use as the entry point. This function should be defined using the WINAPI attribute, and should take three arguments: int WINAPI startup (HINSTANCE, DWORD, LPVOID) This means that the actual symbol name will have an appended @12, so if your entry point really is named startup, the string you should use for ENTRY in the above examples would be entry AT 12. If your DLL calls any cygwin32 functions, the entry function will need to initialize the cygwin32 impure pointer. You can do that by declaring a globale variable _impure_ptr, and then initializing it in the entry function. Be careful not to export the global variable _impure_ptr from your DLL; that is, do not put it in DEFFILE. /* This is a global variable. */ struct _reent *_impure_ptr; extern struct _reent *__imp_reent_data; int entry (HINSTANT hinst, DWORD reason, LPVOID reserved) { _impure_ptr = __imp_reent_data; /* Whatever else you want to do. */ } You may put an optional `--subsystem windows' on the $(LD) lines. The Tcl build does this, but I admit that I no longer remember whether this is important. You may put an optional `--image-base BASEADDR' on the $(LD) lines. This will set the default image base. Programs using this DLL will start up a bit faster if each DLL occupies a different portion of the address space. Each DLL starts at the image base, and continues for whatever size it occupies. Now that you've built your DLL, you may want to build a library so that other programs can link against it. This is not required: you could always use the DLL via LoadLibrary. However, if you want to be able to link directly against the DLL, you need to create a library. Do that like this: $(DLLTOOL) --as=$(AS) --dllname DLLNAME --def DEFFILE --output-lib LIBFILE $(DLLTOOL), $(AS), DLLNAME, and DEFFILE are the same as above. Make sure you use the same DLLNAME and DEFFILE, or things won't work right. LIBFILE is the name of the library you want to create, e.g., libtcl80.a. You can then link against that library using something like -ltcl80 in your linker command. Ian - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".