Calling unmanaged C++ dll from C# app

G

Guest

Background:

We have developed an C# MDI (Multi-Document Interface) application which
loads different assemblies/forms, so that the user can have many "application
windows" running within the same container. Some of these child forms need
to use legacy code from a mature product written in C, and we have achieved
this by compiling our C code into a DLL, and using DllImport directive to
reference the functions that we need. The C# applications are able to use
the functions perfectly, but we are now facing another challenge.


The Challenge:

The C code uses caching to reduce database access delays, and those caches
are simple linked lists or arrays that are global/static. While this
assumption worked well for our legacy application (which is comprised of
numerous stand alone executables that naturally have their own process
space), it doesn't work well for the MDI C# model. That is, two child forms
running inside the MDI would share those caches, since all the
assemblies/forms (and DLLs) share the same process space. However, for our
product, it is unacceptable for two MDI child forms to share the same data
cache (for example, the cached data may have been derived based on user
preferences that are specific to each child form).


Where We're Stuck:

We have been trying to load the DLL more than once into the MDI process
space, where each copy will have it's own static/global variables, and
therefore different cached data, but we were unsuccessful. We attempted
loading them through different Application Domains, but it looks like the
external reference is resolved only once per DLL and reused (i.e. all app
domains reference the same copy of the DLL in the MDI process space).

Of course, we could rewrite the C code to eliminate the global/static memory
assumptions, but this isn't feasible due to the amount/complexity of the
legacy code.

We've also considered managing multiple copies of the dll to overcome this
problem (we've tested this and it works), but we don't want to resort to a
hack like this unless we have no other choice.


The Question:

Does anybody know of a way to load multiple instances of the same unmanaged
C++ dll into the process space of a single C# application (using application
domains or some other technique)?
 
P

Peter Huang [MSFT]

Hi,

Based on my experience, the dll is loaded perprocess and that is why it is
called dynamical link library.
Anyway I will keep research the issue and give you a reply ASAP.

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Huang [MSFT]

Hi

So far I think we have another approach is wrap the C++ dll in a COM EXE
out of proc server, so that every mdi children frame can create its own com
exe server.

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi,

Thanks for the feedback.

MSDN documentation says "Access to in-process objects is much faster than to
out-of-process server objects because Automation does not need to make remote
procedure calls across the process boundary."

So we'd like to avoid this if there is an in-process technique that will
achieve the desired effect.

Thanks,

Chris
 
P

Peter Huang [MSFT]

Hi

I have confirmed with senior engineer that so far we may use COM
Server(EXE), because the dll is loaded per process.
Or I think we have change the dll design which will not be an good
alternative.

If you still have any concern, please feel free to post here.

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Peter,

Thanks for the reply and thanks for asking around. Your time/help is
greatly appreciated.

Concerning the COM server idea, we'd like to avoid an out-of-proc solution
as I mentioned in my last note.

What do you mean when you refer to changing the dll design?

Thanks,

Chris
 
P

Peter Huang [MSFT]

Hi

I am sorry I mean we can use a class member not global memeory to do the
data cache, so that we can make the dll a inproc com server, and each
instacne of the com object can have its own private data.

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Peter,

Thanks again for your help.

As you might appreciate, we're trying to get to a point where have all of
the information necessary to make an educated (management level) decision on
what path to take.

From your replies, it seems clear that we either need to change our code to
eliminate the global variables or we need to use an out-of-proc strategy to
be able to load multiple instances of the same dll.

In other words, there doesn't appear to be a way to load multiple instances
of the same dll within the context of a single process.

Before we close the book on the investigative stage, however, we're
wondering whether it would be worthwhile to officially raise this question
through MSDN technical support. Do you think that there's any chance that we
could learn more about the issue by doing this?

Thanks,

Chris
 
P

Peter Huang [MSFT]

Hi Chris,

Per the issue, I have also discussed with our develop engineer and other
support engineer. Because the win32 dll works per process, the second call
to the LoadLibrary to the same dll, we will just add a ref count on the dll
while not load a new instance, so that the dll will not be unloaded when
the former one ended using the dll. So far we have three approached to
workaround the problem.
1. We can use a COM EXE server which will have the least code change but we
may have performance hit because of the out of proc nature.
2. We need to change the dll not to use the global memory as data cache
which may need many code change but it is inproc.
3. From the design of your dll data cache, we can add the dll export
function call parameter.
3.1 declare the dll export func as below
Func(int id,¡­) id is the mdi child form's indicator
3.2 change the global array and list as an array's array and list, this is
just an idea.
e.g. if we originally use ArrayA and listA as the data structure, now we
can declare a global ArrayG, and the ArrayG[id] will point to the structure
of the ArrayA and listA

Aslo if you wants to contact MSPSS to see if they have further idea is just
OK, you may reach MSPSS via the link below.

http://support.microsoft.com


Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top