Click here to Skip to main content
14,933,538 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am trying to follow Using Shared Memory in a Dynamic-Link Library - Win32 apps | Microsoft Docs[^]

This lesson says to use
BOOL WINAPI DllMain(HINSTANCE hinstDLL,  // DLL module handle
    DWORD fdwReason,              // reason called 
    LPVOID lpvReserved)


I am trying to build a shared regular MFC DLL that will be used by more than one application and need to share the data between different applications.

The MFC Shared dll VS2019 generated class header file does not have DllMain function.

It looks likes

class ControllerApp : public CWinApp
{
public:
	ControllerApp();


public:	
	virtual BOOL InitInstance();
	DECLARE_MESSAGE_MAP()
};


Please advise "How to initialize the code for shared memory in generated code that does not have DllMain?"

What I have tried:

I tried adding

virtual BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);


but it never get called.
Posted
Updated 26-Feb-21 5:56am

That is not a DLL header, it is a Windows Application header. And any dll can be shared by multiple applications; that is what dlls are for. Also, it is not clear what you are trying to achieve by the use of shared memory.
   
Comments
Member 15011436 26-Feb-21 8:18am
   
Hi Richard, Thanks for your time.

I am trying to develop a DLL with capability of sharing data , events between two or more different MFC applications.

For example MFC Application 1 will send x, y, radius of sphere to the dll, then dll should pass these data with some draw sphere event to 2nd MFC application that will draw the sphere.

https://docs.microsoft.com/en-us/windows/win32/dlls/using-shared-memory-in-a-dynamic-link-library

BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle
DWORD fdwReason, // reason called
LPVOID lpvReserved) // reserved
{

This looks part of DLL.
Richard MacCutchan 26-Feb-21 8:47am
   
That would require some form of callback in the second application so that the dll knows when (and how) to pass information back to it. However it would be much simpler to use shared memory (controlled by mutexes) between the two applications without the need for the dll. Alternatively you could use pipes as a communications channel between the two. See Pipes (Interprocess Communications) - Win32 apps | Microsoft Docs[^].
Member 15011436 26-Feb-21 10:18am
   
Using DLL is program design's demand.

I think I am done with most on dll, call back is set.

Application 1 can pass argument and events to dll. When DLL tries to call application 2 callback, it throws access violation error. Then I searched and found your remarks on a old question, that gives idea on shared memory.

Please advise "How to initialize the code for shared memory in generated code that does not have DllMain?" This answer will save my many old work in dll.
Richard MacCutchan 26-Feb-21 11:01am
   
Like I said, using a dll is not the best way to do this. Dlls are not designed to call into applications, but to be called from applications. What you are trying to do is potentially problematic, as you have just discovered. Go to the link I provided above and learn how to do it the best way.
Bhanunjay 26-Feb-21 13:10pm
   
Thank you very much for teaching. I will follow.
Firstly, your DLL does not need to have any association with MFC. For a shared memory implementation it doesn't seem necessary to me at all.

Secondly, it is highly recommended that you do very, very little in your DLLmain code. Microsoft's docs state this also. That's because not all libraries have been fully initialized so you may encounter errors.

Lastly, as Richard mentioned, you don't need a DLL to do this but you certainly can use one. I use static libraries almost exclusively these days and they can accomplish all of the same things except they can't be explicitly loaded and that's OK with me because I don't need or want that.

Anyway, the best way to do this is to make an Initialize or MapMemory function, or what ever you want to call it, and let it map to the shared memory for you. All libraries will be full initialized by the time it is called so this should work OK. I do not recommend that you use callbacks. I find them to be too error-prone. I have better success with signalling events or posting messages. I recently implemented a highly modular system using what I refer to as a subscription model. It allows apps and/or threads to subscribe to events. What that means is a list is kept in shared memory where an app or thread can add the name of an event that gets signalled when certain things occur that they want to know about. This works really well for me.

An alternative that is a bit simpler is you can make a list in shared memory that an app, thread, or window; what ever; will add its window handle and a message code to. This should be protected by a mutex so they don't overwrite each other. When data is available the data source can post a message (PostMessage) to the specified handle with the message code listed. There are two additional arguments available in the message you can use for what ever you want. One idea is to have a array of data and when it is available put it in a slot and then tell the subscriber which slot it is in using the WPARAM or LPARAM of the message you send to it. The subscriber will receive the specified message when the data is available in its normal message loop. Threads can have message loops too so this scheme has a lot of flexibility.

Here's a subscription entry structure you can use that can live in shared memory.
C++
struct SubscriptionEntry
{
    HWND  handle;
    int   msgId;    // something like WM_APP + what ever
    int   wparam;   // subscriber-specified parameter for WPARAM
};
this one assumes the slot index of the data will be placed in the LPARAM of the message. There lots of ways you use this kind of thing. You could have a list for every kind of data you have with multiple subscribers in each one. When data is available you could send it too all the subscribers on the list. In my system, I have a shared memory directory of 255 subscription lists, each with up to 16 subscribers. It uses signalling events because the worker threads don't have message loops but that's just my implementation. It is otherwise very similar.

I hope this helps. If you need clarification feel free to ask.
   
Comments
Bhanunjay 26-Feb-21 13:11pm
   
Thank you very much for teaching. I will follow.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900