DLL Hell: How do I P/Invoke "own" DLL?

B

Benjamin Lukner

Hi!

I've written a DLL using eVC++ 4.0 that ships with our devices and is
used by a VB.Net "system" program that automatically starts on boot.
HKLM\Loader\SystemPath includes the directory of the DLL.

The DLL is also used by a VB.Net application. Now I updated the DLL and
the application and put both into the same directory.

Problem: When the application P/Invokes the dll the file from the system
directory is taken instead of the file from my own directory!

Q: What is the syntax for a VB.Net 2003 CF P/Invoke to tell it to use
the dll from the own directory?

Kind regards,

Benjamin Lukner
 
C

Christian Resma Helle

Hi!

I've written a DLL using eVC++ 4.0 that ships with our devices and is
used by a VB.Net "system" program that automatically starts on boot.
HKLM\Loader\SystemPath includes the directory of the DLL.

The DLL is also used by a VB.Net application. Now I updated the DLL and
the application and put both into the same directory.

Problem: When the application P/Invokes the dll the file from the system
directory is taken instead of the file from my own directory!

Q: What is the syntax for a VB.Net 2003 CF P/Invoke to tell it to use
the dll from the own directory?

Kind regards,

Benjamin Lukner

<DllImport("[YOUR DLL]")> would also work for DLL's located in your
applications working directory. The syntax for P/Invoke in VB.NET
would be something like this:

<DllImport("coredll")> _
Private Shared Sub LocalFree(handle As IntPtr)
 
B

Benjamin Lukner

<DllImport("[YOUR DLL]")> would also work for DLL's located in your
applications working directory. The syntax for P/Invoke in VB.NET
would be something like this:

<DllImport("coredll")> _
Private Shared Sub LocalFree(handle As IntPtr)

That's exactly the problem: IT DOESN'T! :-(

I use (what's an "old style" alternative declaration):

Private Declare Function SDC_WrapperVersion Lib "sdc_wrap.dll" _
( _
) As Int32

sdc_wrap.dll is located in a directory that SystemPath points to and
returns 1.
sdc_wrap.dll is also located in the directory of my exe and returns 2.

But when running my application I always get 1, so the wrong dll is used.

Kind regards,

Benjamin Lukner
 
G

Guest

You tried a fully qualified path to the DLL in your P/Invoke declaration?
The loader looks in \Windows first, so the behavior is expected.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded World
www.OpenNETCF.com


Benjamin Lukner said:
<DllImport("[YOUR DLL]")> would also work for DLL's located in your
applications working directory. The syntax for P/Invoke in VB.NET
would be something like this:

<DllImport("coredll")> _
Private Shared Sub LocalFree(handle As IntPtr)

That's exactly the problem: IT DOESN'T! :-(

I use (what's an "old style" alternative declaration):

Private Declare Function SDC_WrapperVersion Lib "sdc_wrap.dll" _
( _
) As Int32

sdc_wrap.dll is located in a directory that SystemPath points to and
returns 1.
sdc_wrap.dll is also located in the directory of my exe and returns 2.

But when running my application I always get 1, so the wrong dll is used.

Kind regards,

Benjamin Lukner
 
B

Benjamin Lukner

You tried a fully qualified path to the DLL in your P/Invoke declaration?
The loader looks in \Windows first, so the behavior is expected.

Yes, I've read about the search order of dlls.
And no, I didn't try the fully qualified path.
Because the application (and dll) can be located in any folder on the
device.
But DllImport says "Constant expression is required."

How do I fill a constant with a value that I only know by the time my
application starts?

Kind regards,

Benjamin Lukner
 
G

Ginny Caughey [MVP]

Benjamin,

Did you try renaming your own DLL to a different name so there wouldn't
exist a DLL with the same name in the \windows folder?
 
B

Benjamin Lukner

Ginny said:
Did you try renaming your own DLL to a different name so there wouldn't
exist a DLL with the same name in the \windows folder?

I don't want to rename it because it is only a newer version of the
other dll.

The only thing I'd like to know is if there is a chance to P/Invoke a
dll in my own directory if there's another one in the Windows folder...

Kind regards,

Benjamin Lukner
 
G

Guest

You can't. What you should do is make sure the DLL is in the FILES and not
MODULES section of the platform's BIB file, then you can just replace it in
the \Windows folder. Unfortunately the CF provides no other mechanism.

-Chris
 
R

Robert Simpson

Benjamin Lukner said:
Hi!

I've written a DLL using eVC++ 4.0 that ships with our devices and is used
by a VB.Net "system" program that automatically starts on boot.
HKLM\Loader\SystemPath includes the directory of the DLL.

The DLL is also used by a VB.Net application. Now I updated the DLL and
the application and put both into the same directory.

Problem: When the application P/Invokes the dll the file from the system
directory is taken instead of the file from my own directory!

Q: What is the syntax for a VB.Net 2003 CF P/Invoke to tell it to use the
dll from the own directory?

Call the LoadLibrary() API specifying the path of your DLL before calling
any of your imported functions from that DLL. I think if the DLL is already
loaded in your app space before .NET attempts to load it (the first time you
make a call into it), it will use the library already in memory.

Robert
 
B

Benjamin Lukner

An interesting and worthwhile thing to test. Let us know if that works.

Hi!

I did not have the time to check it until now, sorry.

Unfortunately it does not work like hoped.
Seems like there is a list and LoadLibrary() _appends_ the dll to that
list. In other words: It only works if the "system" dll is not loaded
momentarily.

Scenario:

System folder (folder "SystemPath" points to): App1, dll_v1

Programs folder: App2, dll_v2

- App2 executes and invokes dll
-> dll_v1 is used !
EXPECTED

- App2 executes, calls LoadLibrary() and then invokes dll
-> dll_v2 is used
- App1 executes and invokes dll
-> dll_v1 is used
OK

- App1 executes and invokes dll
-> dll_v1 is used
- App2 executes, calls LoadLibrary() and then invokes dll
-> dll_v1 is used !!
NOT OK

What a dll hell ;-) :-(

Kind regards,

Benjamin Lukner
 
G

Guest

What we really need is the CF to support
Marshal.GetDelegateForFunctionPointer. Unfortunately it's not there (and I
don't think it's in 3.5 either).


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded World
www.OpenNETCF.com
 

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