Delphi Dynamic Dll - a global variable

I am busy dll coding, which provides several functions to the host application. This application calls the dll dynamically, loading and freeing it after each function call.

I have no control over the host application. I can only work with DLLs. Is there a way to store some variables in memory so that I can reuse them in every function? Obviously, the global variable is cleared when the dll is unloaded by the host application. Saving dll to file sounds very dirty!

Can anyone suggest a way to assign a variable that I can keep global?

thanks

+6
global-variables dll delphi
source share
8 answers

I think you have 2 main options.

  • offer 2 versions of your function, what you have, plus another one where they pass in the buffer (write, whatever) from which you can read the previous state, and, of course, update the state. Call it the high-performance version of the feature. They will want to use it.

  • Save the state as if you were in a cookie (basically this is what it is).

Option 1 will require changes to the host application, but it would be useful for host application developers to use; Option 2 will not require changes to the host application, but it will not be as effective.

I personally would not be inclined to start resetting the reference count; presumably, the host application is unloaded for some reason, if I were the main developer application, it would annoy me.

+4
source share

Warning, dirty hacking:

You can upload yourself.

Each call to LoadLibrary increases the reference count; FreeLibrary decreases it. Only if the counter reaches zero does the DLL unload.

So, if the first time your DLL loads, you simply load your library again, thus increasing the reference count. If the calling application calls FreeLibrary , the reference count is decremented, but the DLL is not unloaded.

EDIT: As mghi pointed out, the DLL will be unloaded if the process terminates, regardless of whether the reference count is equal or not.

+4
source share

Another solution, if you have a large amount of global data to share, would be to create a Windows service to "cache" state data. You will also need to implement some kind of IPC that works on the border of the process, for example, memory-mapped files, mailboxes, COM (one instance for this case), ect TCP / IP. You may find that this overhead would be more than just writing state to a file, so I would recommend this approach only if the amount of state data is excessive or will only be processed in parts of the whole for each request in your dll.

For a COM approach, a service should do nothing but request (and hold) an instance of the com object that you will use to maintain state. Since this is the only com com object, all requests will be in the same instance, which allows you to keep your state between requests. Requests to the object are serialized, so this can be a performance issue if you have multiple clients requesting data on the same computer at the same time.

+2
source share

The best way is to use a class containing "global variables". You create an instance of the object and specify it as a parameter for the dll functions. But this will not help you, because you cannot change the calling application.

If you need to save global data in a dll, the solution should write it to a file. But this seriously affects performance.

+1
source share

If I were you, I would save the values ​​of these global vars to a file when the dll is freed and loads them when it is initialized. I have no reason to save a dll memory dump to disk.

0
source share

Write the values ​​to the registry when freeing the DLL and read the values ​​from the registry when loading the DLL. Remember to specify the default value when reading discovers that the key has not been set.

Al.

0
source share

I agree with the previous comments about the dangerous global status information, although I can imagine that this might be needed.

I offer a cleaner version of the dirty DR hack that does not lack constancy, as the answer from skamradt:

Very small application:

It has no appearance, it does not appear on the taskbar.

Task number 1: load the DLL

Task number 2: Take it on the command line, run it and wait for it to complete.

Task number 3: unload DLL

Task number 4: Exit.

Installer:

It finds the shortcuts (s) in the main application and changes them so that a small application runs, the original location that the shortcut points to becomes the first parameter.

Results: The DLL remains in memory only as long as the main application is running, but it is not unloaded every time the program unloads it.

0
source share

It may also be useful.

option 1: Create a shared memory area in which your variables supported by the swap file are stored - if you can open this shared memory area, your dll was previously loaded (provided that the "private" name of the shared memory can be named as- something like process_id_yourdllname) - if you can Don't open it, then you create and initialize it for the first time. If you create it, you will not bother to delete it, but if you open it, you will close it - when unloading. I believe that the area will be released when the application closes, as no other applications should access this particular area of ​​"private" shared memory.

option 2: Create a second .dll that exists only for the purpose of managing your global variables. Your dll A can load this dll B, rather than freeing it, putting in dll B everything you need to manage global variables. It should disappear when the application leaves, and I don’t think that you probably need to take care of the (supposedly useless) reference count (since you are not unloading dll B).

0
source share

All Articles