I came across a unique problem while attempting to write custom controls and packing them into a DLL.  My problem was where to stick the SysInit/SysDone routine.  A DLL has a different type of entry point, one that may be called more than once, so I'm leery of placing it in the DLL Entry routine.  Since the objects I'm using doesn't require the startup/shutdown routine I was tempted not to even add SysInit/SysDone until i realized that I had a more reliable location: inside the WndProc for the WM_CREATE and WM_DESTORY messages.  Since I'm writing custom controls, this will be perfect since it could run startup/shutdown code for every instance of the custom control (as long as I don't use any global memory).

So why am I writing this?

The problem is I'm limited to having only ONE custom control per DLL in this fashion.  I have no way of controlling what objects are to be affected by the SysInit/SysDone.  This is because everything is being MACRO compiled at once.  The only way I can think of to allow for two unique object 'namespaces' to be compiled together and stored into a DLL is to build each once separately in separate *.OBJ's and link them into one more encompassing DLL.  I haven't tried this yet, but I thought I would point out the limitation.  You seem to be full of bright idea's these days, so I thought I would bring the issue into the lime light to see what comes of it :)

Best Regards,
Posted on 2006-08-08 23:05:16 by NaN
Hi NaN
First of all, itís nice to see your are back!

Iím using this code to initialize a DLL. Iím not aware of a problem with it.
SysInit  is called only once on the DLL attach. All included objects calls their Startup method (BoundMethod) if defined. SysDone is called the same way on detach making the object housekeeping calling the defined Shutdown methods.

DllMain proc public hDllInstance:Handle, dReason:dword, dReserved:dword
    mov eax, dReason
    .if eax == DLL_PROCESS_ATTACH
      SysInit hDllInstance
      DbgText "Dll attached"
      m2m hInstance, hDllInstance
    .elseif eax == DLL_PROCESS_DETACH
      DbgText "Dll dettached"
    xor eax, eax
    inc eax
DllMain endp


Posted on 2006-08-09 05:01:54 by Biterider
My concern with that approach is the following:

(1)  You write your controls all in one DLL, and when attached to a process, the startup does any initializations globally for the controls.
(2)  Your process is running happily and displaying the controls as needed (say one is persistant through the entire process).
(3)  At some point, with out quiting this processs, a new process is started, perhaps uniquely different program, but uses the same controls
(4)  As it starts up, it calls the very same assembly code and potentially corrupts the global memory that the first process depends on.

Im probably being overly concerned over nothing, as I dont ever need to spell out a Startup/Shutdown routine in the objects, but I really dont know if any of the objects I'm inheriting from does. 

What do you think?
Posted on 2006-08-09 19:14:13 by NaN
Instead of talking about it, I decided to put it to the test and found I was half correct.  As expected, every process attached/detached to the DLL will execute the Startup/Shutdown methods.  However, in the startup method, incremented an object variable that is defined as 0 in the Object definition.  Likewise, in the shutdown method I placed a decrement to the same variable.  Lastly, I wrote an exportable proc that created an instance of the object, and then call an object method that will show a message box which displays the current value of the variable.

To my surprise, the variable remained constant at 1 no matter how many concurrent processes were attached (and hence called the startup routine). I expected each process to affect the template in the DLL memory sequencially as more processes attach.  I expected the number to reflect the number of active processes attached to the DLL.  For me, this is a good thing, but im still surprised this is the result. 

Posted on 2006-08-09 23:05:59 by NaN
All the joys of the paging mechanism and COW :)
Posted on 2006-08-09 23:33:20 by SpooK
Hi NaN
You have to think about DLLs like other resources.
Each process has a single copy and is responsible to manage it. Internally for the OS, this may be different, but each process has an exclusive (non shared) data section.


Posted on 2006-08-10 00:53:48 by Biterider
Ah...¶nbsp; my bad! (Spiders in the attic it would seem).

I'm confusing .dll .Data? memory with memory mapped files, and the fact that you can share data between process (through the use of a dll) via memory mapped files.

I was blurring this fact into the assumption that the .data segment itself is common to all process attached.

The things you forget when you're a parent... ;)

Posted on 2006-08-10 18:36:20 by NaN
There is one thing that has been nagging me ever since this conversation:

Com must do more than simply renaming DLL's and having a more structured approach to linked libraries.  I know that ClassFactory objects increment an internal counter that is stored in the DLL's memory to keep track of how many COM objects are in use (through various processes).  So how come in this case the number will increment as more objects/processes are created, and not in my simple DLL test?

Posted on 2006-09-04 16:47:59 by NaN

if multiple apps are using the DLL, that shouldn't increase the reference counter, since processes have a private memory space (unless of course your object is already shared across multiple processes, of course).
Posted on 2006-09-04 17:50:13 by f0dder
Hi NaN
If you are speaking of a server in a DLL, then it is a ?in process server?. That means that all the code is placed in the same process as the client. The instance counter of each COM-Object is per process basis. It has no way to know what is running in another process.

Exe and Remote Servers have other mechanisms (stubs and proxies) that allow to ?share? the code beyond the process boundary. This is a more advanced topic. IIRC, Japheth has an example on his homepage.


Posted on 2006-09-05 01:06:23 by Biterider
Thanks for you thoughts.  I thought the reference pointer tracked *all* COM objects created, regardless of process.  So there must be more going on behind in the OS before it unloads a DLL.  Having a ref count of 0 is obviously process dependent, and would have to ensure all process agree before it actually unloads.

Thanks allot.
Posted on 2006-09-09 16:53:43 by NaN