Link to home
Start Free TrialLog in
Avatar of SwaroopMS
SwaroopMS

asked on

Getting a DllNotFoundException when calling an unmanaged dll from C# using DllImport

Hi,
    I'm badly stuck with this one.  

I have  C# application and I want to call an unmanaged dll from this C# application.  I used the DllImport attribute but I get a DllNotFoundException when I make this call.  I've double checked that the dll is in my \bin\debug directory (same as my C# application directory)

However, a call to a standard windows dll (I tried user32.dll and created a messagebox) works fine.  

What am I missing here?  (and by the way.. this is in Visual Studio 2005 and CLR 2.0)

Thanks,
Swaroop
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

I believe that DllImport requires the DLL to be in the searchable path.

Bob
Try placing the DLL in the \bin directory.
Add your \bin\debug directory path to the system's PATH variable.
http://support.microsoft.com/default.aspx?scid=kb;en-us;310519&sd=tech
Avatar of SwaroopMS
SwaroopMS

ASKER

I tried adding the path to my \bin\debug directory to the path environment variable.

I still get the same exception

"An unhandled exception of type 'System.DllNotFoundException' occurred in SimpleTest.exe
Additional information: Unable to load DLL 'WinSSCommon.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)"

I'll try putting the dll in the bin as per Erick37

Thanks,
Swaroop
When you deploy the application, the \debug directory will not be there.  
All referenced DLLs should be in the \bin directory along side your executable.
It did not work with the dll in the bin folder as well.
Try it in the system folder (i.e. C:\Windows\System32).

Bob
Still no luck (with my dll in the system folder).  

I'm totally stumped by this.  It should atleast find the dll...
And I've also ensured that build types match  (both my application and the dll were built in debug mode)
Could you show us the declaration for the DLL?  Also, where did this DLL come from?  And, finally, what does it do?

Bob
Elsewhere I read that I need to register the dll to make it visible.  But my understanding is that its required only if its a COM dll right... This dll of mine is a simple dll tha exports functions (and anyway regsvr32 failed on it when I tried to register it)

Swaroop
Registering the DLL is only required for COM dll's.

Bob
The dll has an entry point with the signature

extern "C" Bool DllMain(..)

and all other funcitons are

DLLNAME_API returntype functionname(...)

DLLNAME_API evaluates to __declspec(dllexport) if I'm not mistaken.
What are the DLL exports?

    dumpbin WinSSCommon.dll /exports

Bob
ASKER CERTIFIED SOLUTION
Avatar of Erick37
Erick37
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
1) Use the depends.exe tool to walk the dependency chain for the unmanged dll.  Make sure all required dll's are somewhere in the path. (Being in the same directory as your application is just fine.)
2) Once you have all the dll's available, the error message may change to "Runtime Error. R6034.An application has made an attempt to load the C runtime library incorrectly."  This can happen for managed code calling a third-party unmanaged dll.  It's a problem with side-by-side assemblies and manifest mis-match. The full details are explained well here (  
http://www.grimes.demon.co.uk/workshops/fusWSThirteen.htm) but the long and short of it is that the unmanaged dll's need to have a proper manifest.  E.g. foo.dll needs a manifest. The sticking point is, that contrary to the documentation, a foo.dll.manifest file, containing the manifest for foo.dll does NOT work.  Rather, the manifest must be embedded in the dll file itselft, under resource id 2 (resource id 1 for .exe's). The linker can do this, or Microsoft's manifest tool, mt.exe, can do it.  Assuming the unmanged dll is foo.dll, and assuming you have a manifest (from the linker or the dll supplier) called foo.dll.manifest, then this manifest can be inserted as a resource with the following command:
mt /manifest foo.dll.manifest /outputresource:foo.dll;#2
You can dump the resouce to see if was added correctly with:
mt /inputresource:foo.dll;#2 /out:dump.txt
Make sure all unmanaged dlls in the depenency chain have proper manifests.