[comp.windows.ms] Data Segments for DLL's

bill@polygen.uucp (Bill Poitras) (12/11/89)

Is it true that a DLL can have a heap (like for linked lists etc.)?

If so, does a DLL create a data segment for each instance of each program
that calls the library?

My ultimate goal is to implement a group of DLL's that will allow me to
write several display list oriented graphics applications, and I don't want
to have to implement a multisegment display/object list.  The way want it is 
the following:
		Display List manager - worries about lines, rectangles, ellipses
		Object manager - worries about the non-graphical information about
						 certain objects: data base blocks, complex symbols
						 spreadsheet cells, etc.
		Message manager - accepts messages and knows  which module to
						 dispatch them to.

The last DLL will be necessary to implement a platform independant system. 
The other platforms will be Mac and Motif/X11.

Any help will be greatly appeciated. 


+-----------------+---------------------------+-----------------------------+
| Bill Poitras    | Polygen Corporation       | {princeton mit-eddie        |
|     (bill)      | Waltham, MA USA           |  bu sunne}!polygen!bill     |
+-----------------+---------------------------+-----------------------------+

jvc@mirror.UUCP (Jim Champeaux) (12/12/89)

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.)?
>
>If so, does a DLL create a data segment for each instance of each program
>that calls the library?
>
>...

Yes, a DLL can have a local heap.  To use the local heap, however,
the library must initialize it by using the LocalInit function in the 
library's initialization function.

A DLL can have only one instance of a data segment.  "In general, if
a library needs to save data specific to an application, the library
should allocate space in its local heap, copy the data to the
allocated space, and return the data's local handle to the
application.  When the application wants the data back, it can supply
the handle."

See _Microsoft_Windows_Programmers's_Learning_Guide, Appendix C,
Windows Libraries, for more information.

mguyott@mirror.UUCP (Marc Guyott) (12/13/89)

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     <PUBLIC,rsrvptrs>
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    <FATALEXIT>

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 <PUBLIC,__astkovr>
	mov	al,-1
	db	0BBh

labelNP <PUBLIC,__cintDIV>
	mov	al,-2
	db	0BBh

labelNP <PUBLIC,__fptrap>
	mov	al,-3

	cbw
	cCall	FATALEXIT,<ax>
sEnd	CODE

externFP    <LocalInit>
externFP    <UnlockSegment>
externFP   <main>

sBegin	CODE
assumes CS,CODE

cProc __astart,<PUBLIC,FAR>
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,<ds,ax,cx>
	mov   ax,-1
	cCall  UnlockSegment,<ax>
	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,<ax,argv>

	add	sp,10			; Pop parameters to __astart.
cEND	__astart

sEnd	CODE

end __astart
----

bturner@hpcvlx.cv.hp.com (Bill Turner) (12/13/89)

> Is it true that a DLL can have a heap (like for linked lists etc.)?

Yes.

> If so, does a DLL create a data segment for each instance of each program
> that calls the library?

No, there is only one instance of a DLL, and it can have at most one DS.
This is one way to share data between apps (and is how the clipboard works,
BTW) -- have routines that copy data into/out of the DLL's DS.

--Bill Turner (bturner@hp-pcd.hp.com)
HP Corvallis Information Systems