Unmanaged DLL doesn't work in Windows 7 - c#

Last week I stumbled upon a problem and I'm not sure how to solve it. I already spent a whole day to try to solve it alone.
I have an unmanaged DLL that worked fine in my C# code on a Windows XP (32 bit) System. When I try to run this C# code on a newer System (for example Windows 7 (64 bit) it doesn't work anymore.
This is the code
[DllImport("MyTest.dll")]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern String DoSomething();
As I said this works fine on my Windows XP System but doesn't work on my Windows 7 System. When I try to run this code on my Windows 7 System I get the following Exception (translated into English)
The DLL "MyTest.dll": Recurrence too deep, Stackoverflow. (Exception from HRESULT: 0x800703E9) can not be loaded.
I'm guessing the problem is because of this:
Load 32bit DLL library in 64bit application
How to call win32 dll in windows 7
I'm just not sure about it because when I search for my exception in combination with DLLImport I can't find anything.
If this is really the problem what would be the best solution?

You could check:
unmanaged dll dependencies with dependency walker. There might be missing c++ redistributable. Look for MSVCR{xxx}.dll where {xxx} specifies version of the redistributable.
compilation settings of managed application that in the end loads unmanaged dll (Any CPU, x86 or x64). Might be that managed application is set to Any CPU but unmanaged application is x86 and therefore load of unmanaged dll fails.
installed .NET frameworks on windows xp and windows 7. The problem might be different patches applied on .NET frameworks but this is the least likely to be your problem.

I solved the problem like this:
[DllImport("MyTest.dll", CharSet = CharSet.Ansi)]
private static extern IntPtr DoSomething();
public static string Do_Something()
{
IntPtr tempPointer = DoSomething();
string tempSomething = Marshal.PtrToStringAnsi(tempPointer);
return tempSomething ;
}
The problem had to do with a corrupted heap. The handling of corrupted heaps is different in newer version of Windows and because of that my application crashed. It can be solved through changing the C#-Code or the C++-Code.
Detailed information about the problem can be found here:
http://blogs.msdn.com/b/asiatech/archive/2009/12/24/net-application-may-crash-on-windows-2008-when-calling-function-from-native-c-dll.aspx

Related

C# Dll import not working with some computers

I have a C++ dll compiled using VS2013.
I call it in my C# application like this :
[DllImport("myDLL.dll", EntryPoint = "RestartIfNecessary", CallingConvention = CallingConvention.Cdecl)]
public static extern bool RestartIfNecessary(uint uiAppId);
And it works fine.
However once the application is in prod some users have the following error :
Unable to load DLL 'myDLL.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
I can't find why this error happens on some computers. We've been able to fix the issue for some users by removing Microsoft Visual C++ 2013 Redistributable (x86) and (x64) and installing them again.
My C# application is compiled to run on x86.
I have a 64bits w10 and it works fine, so I don't know if it's related to windows.
Have you any hint to help me fixing this issue ?
EDIT: Here are the results of dependency walker :
In dependendy walker I've found 3 dll in red, I don't know if they are important:
API.dll is a third party dll (myDLL is a wrapper for this API)
The error means either myDLL.dll itself, or one of its dependent DLLs, cannot be found on the DLL search path.
Make sure myDLL.dll is placed where your app can find it. You can load myDLL.dll into Dependency Walker on the problematic computers to pinpoint any missing dependencies.

c# calling LoadLibrary from a 64-bit process to load a 64-bit library fails

I'm having a problem on a machine while attempting at loading a library with a P/Invoke call to LoadLibrary.
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr LoadLibrary(string dllToLoad);
This is my configuration. The calling assembly (A) is compiled in x64 and it calls another assembly (B) compiled as AnyCPU. From B I call LoadLibrary(dll_C_Path) to a library C that is 64-bit. All this works on my machine running Win10 64-bit, but it fails on another machine running Win7 64-bit with the following error (after calling GetLastError): "%1 is not a valid Win32 application".
On B, before calling LoadLibrary I've verified that Environment.Is64BitProcess=true. I've opened the library C with DependencyWalker and it appears 64-bit. But the most strange thing to me is that on one machine works while on another not. What can be the cause?
EDIT
I'm passing the full absolute path to LoadLibrary. Here below a screenshort from Depency Walker (library C is aec.dll). I'm not used to it, but one thing I noticed is that the msvcr120.dll, which aec.dll depends on, has not the icon of a 64-bit. Can this give some hint?
There are two possible explanations:
Your code finds a 32 bit DLL, or an otherwise invalid image. We don't know whether you rely of the DLL search path or specify an absolute path.
Your code finds a 64 bit DLL but when it resolves its dependencies, a 32 bit or otherwise invalid module is found.
You should do some debugging to work out what is wrong. I would write a simple C++ program to load the library and avoid the extra complexity of p/invoke. I'd use Dependency Viewer in profile mode to determine which dependency is not valid.

Native DLL Not found

I have a program that uses Tesseract to extract text from images. I made a Native C++ DLL that is used in C# via P/Invoke. My C# application is a console x64 based and the DLL is also 64 bit.
After deploying to a Windows Server I receive an error that suggets the DLL (one I've made) does not exists. The error message is below.
System.DllNotFoundException: Unable to load DLL 'TesseractX64.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) at Utilities.Finance.PDFParser.PDF.OCRObject.GetUTF8Text(String path, String lang, String imgPath)
I know for sure that the DLL exists in that path. The TesseractX64.DLL is placed in the same folder as the C# application so it should work without any issues.
Here is my code:
[HandleProcessCorruptedStateExceptions]
[DllImport(#"TesseractX64.dll", EntryPoint = "GetUTF8Text", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetUTF8Text(string path, string lang, string imgPath);
What I have tried so far:
Set the DLLImport path to a relative path for example C:\DLL\Tesseract.DLL. Still same issue.
Installed Visual C++ 2005 - 2012 both x86 and x64. Still same issue.
It works perfectly fine on my Windows 7 x64 computer that I used to develop the program.
Either:
The DLL cannot be found, or
One of the DLL's dependencies cannot be found.
Place the DLL in the same directory as the executable to ensure that it can be found.
Make sure that all the DLL's dependencies are met on each machine that needs to run your software. That will involve first working out what those dependencies are. The documentation for the DLL should tell you that information. Typically this means installing the MSVC runtime against which the DLL was linked.
You aren't allowed to redistribute the debug runtime. You'll want to make a release build of the native DLL even if the .NET code is in debug mode.

When loading managed c++ dll using Assembly.LoadFrom() receive file not found exception

I am developing an add-in using VSTO for Microsoft project and I have a managed c++ dll that wraps an un-managed c++ dll. I need to deploy two versions of the managed c++ dll one for 64 bit and one for 32 bit. I am using Assembly.LoadFrom(path) to load the appropriate dll depending on which version of Office I am running from. This all seems to work fine on my development machine which is a 64 bit machine running 64 bit office. Below is the code in question:
try
{
//This will return true so I know the file exists
bool fileExists = File.Exists(path);
//This will throw a file not found exception
keyModAssembly = Assembly.LoadFrom(path);
}
catch (FileNotFoundException e)
{
}
I have triple checked the path and the file exists and is the correct 32 bit dll. This all works fine on my 64 bit machine but fails in xpmode when I am trying to test it for 32 bit versions.
any suggestions would be greatly appreciated.
Thanks in advance.
Edit
In response to Phillip's suggestion about the unmanaged dll possibly not being found I am loading the unmanaged dll into scope using the LoadLibraryW(path).
// this is not throwing an exception so I know the unmanaged dll is there.
if (!File.Exists(unmanagedPath))
throw new FileNotFoundException();
LoadLibraryW(unmangedlibPath);
Could it be that the wrapper assembly (which I assume is what path points to in your example) is loaded correctly, but the native DLL which it references is not found? You are not checking for that one in your code. Often the error message says 'Assembly or one of its dependencies is not found'.
A good way to investigate this is to use either procmon from the SysInternals tools to monitor the file system access (which will tell you where the system is looking for your 32-bit DLL) or use the Fushion facilities in Windows.

C# interface C++ DLL?

How do I call functions from a C++ DLL?
The C++ DLL contains functions like this:
__declspec(dllexport) bool Setup () { return simulation.Setup (); }
The C# program does this:
[DllImport("mydll.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Setup();
The C# program crashes with the following message when it tries to load (?) the DLL:
An unhandled exception of type 'System.BadImageFormatException' occurred in TestFrame.exe
Additional information: There was an attempt to load a file with a wrong format (exception from HRESULT: 0x8007000B)
The C++ DLL is a standard DLL (no MFC, no ATL).
This error occurs when you try to load a 32-bit DLL into a 64-bit process. (Or vice-versa)
Until VS2010, C# projects are target any CPU by default and will run as 64-bit on a 64-bit OS.
You need to go to the Build tab in Project Properties and set the C# project to x86 only.
Is it possible that your exe and dll have different bitness (i.e. one is 64 and the other 32)?
Have you tried compiling the code for x86 platform?
See this blogpost for instructions.
It may not be appropriate for you to set the CPU architecture (platform target) for the assembly, but instead you can specify an alternate path to find the correct DLL to load.
How to use the correct unmanaged DLL file according CPU architecture? (32 / 64 bits)

Categories