Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!uunet!husc6!spdcc!mirror!mguyott From: mguyott@mirror.UUCP (Marc Guyott) Newsgroups: comp.windows.ms Subject: Re: Data Segments for DLL's Message-ID: <33876@mirror.UUCP> Date: 12 Dec 89 17:51:36 GMT References: <606@fred.UUCP> Reply-To: mguyott@prism.TMC.COM (Marc Guyott) Organization: Mirror Systems, Cambridge Mass. Lines: 252 In article <606@fred.UUCP> bill@fred.UUCP (Bill Poitras) writes: >Is it true that a DLL can have a heap (like for linked lists etc.)? Yes a DLL can have a heap. >If so, does a DLL create a data segment for each instance of each program >that calls the library? I believe that can be either one data segment for all instances of a DLL or a different data segment for each DLL. We use one data segment for all instances of our DLL. This means that any information that is unique to an instance must be stored in global memory (you can store a handle to a chunk of global memory in the window extra bytes) or as a local (read allocated from the stack when the routine is called) variable. This is what we do to create a DLL with one data segment for all instances that also has a local heap: add the following to your .def file: DATA MOVEABLE SINGLE HEAPSIZE 4096 Windows will grow the heap dynamically for you if necessary. You do not need to specify a large heap size initially. Of course, if you know you will need a lot of heap space .... Assemble the libaux.asm with the command line: masm -D?MLIBW -MX libaux.asm Compile stdmain.c and then link both of these .obj files into your DLL. stdmain.c and libaux.asm are at the end of this posting. The call to LocalInit() in libaux.asm is what allows Windows to set up your local heap. I hope this helps, Marc ---- "All my life I always wanted to BE somebody. I see now I should have been more specific." Jane Wagner Marc Guyott mguyott@mirror.tmc.com {mit-eddie, pyramid, harvard!wjh12, xait}!mirror!mguyott Mirror Systems Cambridge, MA 02140 617/661-0777 ---- stdmain.c #include "windows.h" HANDLE hModule; /* Instance handle (for Main) */ /* * main -- standard procedure for "gluing" library to main application. */ int FAR PASCAL main(argc, argv) int argc; /* argc == 5 */ HANDLE FAR *argv; /* argv[0] automatic data segment */ /* argv[1] size of heap */ /* argv[2] module handle */ /* argv[3..4] command line farp */ { hModule = (HANDLE) 0; if (argv[0] && argv[1]) { hModule = argv[2]; } return ((int) hModule); } ---- libaux.asm ;------------------------------------------------------- ; ; Windows library start up module. ; ; 09/11/86, KR ; From Application Note 10. Windows "Library" utility. ; if1 ?WINLIBC = 0 ?PASCAL = 0 ifndef ?PASLIBW ifndef ?MLIBW ifndef ?SLIBW ?WINLIBC = 1 ifndef ?MLIB memS = 1 %out ! Compiling for WINLIBC.LIB else memM = 1 %out ! Compiling for MWINLIBC.LIB/LWINLIBC.LIB endif else memS = 1 %out ! Compiling for SLIBW.LIB endif else memM = 1 %out ! Compiling for MLIBW.LIB/LLIBW.LIB endif else ?PASCAL = 1 memM = 1 %out ! Compiling for PASLIBW.LIB endif ifndef ?OEMLIBC ?LIBOEM = 0 else ?LIBOEM = 1 %out ! Compiling for OEMLIBC.LIB endif endif .xlist ?DF = 1; ?PLM = 1; ?WIN = 1; include cmacros.inc .list ; ; Define single code segment ; createSeg _TEXT,CODE,PARA,PUBLIC,CODE ; ; Define data segment order for data. Para alignment. ; createSeg NULL,NULL,PARA,PUBLIC,BEGDATA,DGROUP createSeg _DATA,DATA,PARA,PUBLIC,DATA,DGROUP createSeg CDATA,CDATA,WORD,COMMON,DATA,DGROUP createSeg CONST,CONST,WORD,PUBLIC,CONST,DGROUP createSeg _BSS,_BSS,PARA,PUBLIC,BSS,DGROUP createSeg XIB,XIBSEG,WORD,PUBLIC,DATA,DGROUP createSeg XI, XISEG, WORD,PUBLIC,DATA,DGROUP createSeg XIE,XIESEG,WORD,PUBLIC,DATA,DGROUP createSeg XPB,XIBSEG,WORD,PUBLIC,DATA,DGROUP createSeg XP, XISEG, WORD,PUBLIC,DATA,DGROUP createSeg XPE,XIESEG,WORD,PUBLIC,DATA,DGROUP createSeg XCB,XCBSEG,WORD,PUBLIC,DATA,DGROUP createSeg XC, XCSEG, WORD,PUBLIC,DATA,DGROUP createSeg XCE,XCESEG,WORD,PUBLIC,DATA,DGROUP defGrp DGROUP,DATA sBegin NULL DD 0 labelDP maxRsrvPtrs = 5 DW maxRsrvPtrs DW maxRsrvPtrs DUP (0) sEnd NULL sBegin DATA assumes DS,DATA public __acrtused __acrtused = 1 if SizeC globalCP __aaltstkovr,-1 ; endif sEnd DATA externFP sBegin CODE assumes CS,CODE PUBLIC __chkstk,_chkstk,chkstk __chkstk: _chkstk: chkstk: pop bx if sizeC pop dx endif sub ax,sp neg ax chkstk1: mov sp,ax if sizeC push dx push bx ccc proc far ret ccc endp else jmp bx endif labelNP mov al,-1 db 0BBh labelNP mov al,-2 db 0BBh labelNP mov al,-3 cbw cCall FATALEXIT, sEnd CODE externFP externFP externFP
sBegin CODE assumes CS,CODE cProc __astart, cBegin ;; ;; DS = automatic data segment. ;; CX = size of heap. ;; DI = module handle. ;; ES:SI = address of command line (not used). ;; push es push si push di push cx push ds mov si,sp xor ax,ax cCall LocalInit, mov ax,-1 cCall UnlockSegment, mov ax,5 ; Count of arguments. Argc. regptr argv,ss,si ; SS != DS. Far pointer Argv. ;;cCall __cinit ; Not called because all "C" librarys ; assume ss == ds. ; ; main( argc, argv ) ; cCall main, add sp,10 ; Pop parameters to __astart. cEND __astart sEnd CODE end __astart ----