I get this error from within a normal C# console program that's consuming a DLL produced as the build output of a C++ CLI project. There I have a simple DumbThing public ref class with a static method. I'd like to simply call that function or at least instantiate one tiny DumbThing object and see that C# can call code that it gets from a C++ CLI born DLL, but it's not working as it throws an error that puzzles me even more:
First-chance exception at 0x000007fefd2acacd (KernelBase.dll) in DumbTest.exe: Microsoft C++ exception: EEFileLoadException * __ptr64 at memory location 0x007fc228..
UPDATE: below the original exception, there's another first chance exception:
First-chance exception at 0x77cace3b (ntdll.dll) in DumbTest.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
A colleague pointed out to me that it might be a compile time issue (some options), but I don't have any clues what could cause it. Could anyone please provide some starting point hints?
It's probably a bitness issue. If you compiled your C++/CLI project for a specific platform, be sure that your C# project has set its platform accordingly. Default for C# projects is "Any CPU" which causes the JIT compiler to generate x64 code on a 64-bit architecture. If your C++/CLI project was built for x86 then it can't be loaded into a x64 process on a 64-bit machine.
Related
I'm trying to instantiate a COM object, defined in a x86 dll written in Borland C++, in a testing program i write in C# (.net 4.7.2). The COM dll (server) is working, I have a windows service also written in C++ Borland that can use it and instantiate a COM object from the class (using CoCreateInstance). The dll is registered and the InprocServer32 entry has the correct path to the dll. There is no coclass existing in a typelib, only interfaces (those exist in the typelib). I have used the TlbImp to create dll:s which i reference in the c# project. In the project the target platform is set to x86. The way i try to instantiate an object is:
var comType = Type.GetTypeFromProgID("ins.MyComType");
object comObj = Activator.CreateInstance(comType);
however the second line gives me
"Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll"
with the message 'Retrieving the COM class factory for component with
CLSID {C4363C5E-3831-46DF-8701-60C8D1B612BA} failed due to the
following error: 8007007e The specified module could not be found.
(Exception from HRESULT: 0x8007007E).".
It does not matter if i try to run the app as administrator. I have a vague memory of trying out a similar thing a couple of years ago and that it at that time worked. It was probably on a Win 7 machine (might even have been a 32-bit system). I have tried to open the project in DependencyWalker but i'm not sure what i'm looking at. I get a couple of errors:
*Error: At least one required implicit or forwarded dependency was not found.
*Error: Modules with different CPU types were found.
*Error: A circular dependency was detected.
*Warning: At least one delay-load dependency module was not found.
*Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
Does any one have any idea on what it could be causing the exception? Or if i could get some hints as of how to dig deeper into dependencywalker? I get a gigantic tree of systemassembly stuff but i cannot see any obvious assembly standing out, though DW refers to many of them as being 64 bit. My guess is some dependent dll(s) somewhere should be x86 but which one(s). Is there a redist similar thingi i should have installed for this to work?
best regards
/Erik
You should write a simple VBScript that contains these lines:
set obj = CreateObject("ins.MyComType")
MsgBox TypeName(obj)
Name the file test.vbs
Execute the command:
c:\windows\syswow64\wscript.exe test.vbs
Using the version from syswow64 ensures that it uses the 32-bit version of wscript.exe which can instantiate 32-bit COM objects. The version in c:\windows\system32 can only instantiate 64-bit In-process COM objects in DLLs...you said your object is a 32-bit COM DLL server.
If the vbscript fails, it could be that the object is not automation compatible--implements IDispatch. Otherwise you will get an error message why it fails.
If it succeeds, you will know there is probably nothing on the C++ side causing problems. You THINK this is the case...but where is the runtime for Borland C++? Is everything statically linked, or is some of it dynamically linked? If it is dynamically linked, where is it in the path? It could be that the C++ service you have has the library in its path so that when it loads your COM object, the library is available. But, when you try to load from a 3rd party, like .NET or VBScript then the path to the library manifests itself. Who knows? I'm just making suggestions.
If you use ProcMon, it can see where the problems are. It will show you what registry entries are being read and which files are trying to be loaded.
I have a C++ dll project, which will be called by the C# Windows Application. But each time when I tried to write to files in the C++ dll project, I will get the following error:
An unhandled exception of type 'System.AccessViolationException' occurred in Wrapper.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
When receiving this error, the code pointers to the _Lock() of file fstream:
The code I am using in the C++ dll project is:
ofstream ofs("debug.txt"); // OK
if (ofs.good()) // OK
ofs << "aaa" << endl; // this line causes the error <--
ofs.close();
Other info:
Developed under VS2010-Winx64 (.NET Framework 4).
Wrapper is the managed C++ project that wrappers the C++ code for being called in C#.
I checked the debug.txt file, which is writable.
Any suggestion is much appreciated. Thanks.
It turns out that I am mixed up in setting the runtime library. Changing the runtime library from /MD to /MDb of the C++ dll project fixed the problem.
In VS2010, this can be done in:
Project -> Properties -> Configuration Properties -> C/C++
-> Code Generation -> Runtime Library -> Multi-threaded Debug DLL (/MDd)
I'm looking at code that is new-to-me. I have c++ code in a project called UI, with a number of dependencies, which builds correctly and doesn't return any errors. In the same solution in Visual Studio 2008, I have created a new C# windows forms project and added a reference to the dll generated by the UI project, and added a "using" statement. What I want to do is raise one of the dialogs that are defined in the UI project, so I have code like
UIDialog uIDialog = new UIDialog();
uIDialog.Show();
which builds.
When I run my project in debug, when it gets to the "new" part, I get the exception above - with no information as to what the missing module is.
Is there any way to find out what the missing module is, without digging through the code in the UI project?
(I'm trying to rephrase this question so that it doesn't get closed. If someone could give the definitive answer of "No, there isn't" I'd find that very helpful. Thanks also to those who closed the previous version.)
Edit:
System.IO.FileNotFoundException occurred
Message="The specified module could not be found.
(Exception from HRESULT: 0x8007007E)"
Source="ui"
StackTrace:
at ui.UIDialog.Startup()
at ui.UIDialog..ctor() in c:\..\ui\UIDialog.h:line 61
InnerException:
That's the problem, there's no useful information anywhere obvious!
It's not a 32/64 bit problem - before getting here, I had the typical "BadImageFormatException", so to get past that I forced everything to be 32bit.
You could use the MSIL Disassembler on the referenced dll and check the manifest for all the dependencies of the dll. The disassembler is part of the Windows SDK tools.
Or there is always DependencyWalker, though I haven't used it in years.
You can turn on Fusion logging to see what the loader is doing and find out what's missing.
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.
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)