Identifying problematic dependencies in C++/CLI pr

2019-06-16 06:55发布

问题:

My application compiles fine, but I get the following runtime error:

System.IO.FileNotFoundException was unhandled
  HResult=-2147024770
  Message=Could not load file or assembly {Wrapper} or one of its dependencies. The specified module could not be found.

The reference to Wrapper in the calling Application looks correct. The Wrapper dll exists in the correct location.

This project used to build and run on someone else's system, I saw it demonstrated several times. That person/computer is no longer available. Some paths of some dependencies have changed since the last time it was successfully built and run, I have fixed all compile errors related to this.

Just to clarify my project structure:

Digraph G
{
    App [ label = "My C# Application"]
    Wrapper [ label = "C++/CLI Wrapper"]
    Lib [ label = "C++ Library"]
    Dll [ label = "My helper C# DLL"]
    CDep [ label = "Series of deep C++ dependencies managed \n by CMake for Lib, hard coded relative paths for Wrapper."]
    App->Wrapper->Lib->CDep;
    App->Dll->Wrapper->CDep;
}

Wrapper is a C++/CLI wrapper around a C++ library. The error is triggered when we try to load a class in the Application that has a using statement for the Wrapper.

Wrapper does have a lot of dependencies, but the error message does not indicate which dependency is problematic. This is a large, complicated system, most of which is built by other teams. The C++ components use CMake to get all the dependencies correct, but CMake does not natively support C#.

I tried using fuslogvw to find the binding error, but it showed me absolutely nothing until I changed settings to include all binds, and then it only showed successful binds. http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.100).aspx

The paths are long, but not over 256 characters.

I had a warning in the compile for Dll (see graph above): Warning 1 There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "{cli_wrapper.dll}", "AMD64". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.

In Configuration Manager, the Dll is building for Platform "Any CPU" and Wrapper is building for "x64". I changed the dll to x64. I still get the runtime error.

Could not load file or assembly or one of its dependencies Performed a clean, deleted build directory contents. No change. Re-opened Visual Studio. No change. Tried changing assembly name, default namespace, and project name to match. No change.

Could not load file or assembly 'xxx' or one of its dependencies. An attempt was made to load a program with an incorrect format I believe we have to compile for 64 bit. We are dependant on a 64 bit C++ library.

Could not load file or assembly ... The parameter is incorrect I am local administrator.

How to enable assembly bind failure logging (Fusion) in .NET Tried the registry settings, but they appear to just be fuslogvw settings. No improvement in available log data.

Many other similar questions had ASP or service install specific answers.

回答1:

I found the problem. There was more than one version of the library available to me, and I was using the include files from one version and the compiled library of the other. Dependancy Walker was key to finding which library had the problem, and if Aschratt had posted that as an answer rather than as a comment I would have accepted his answer.



回答2:

I had the same error with a similar project earlier this week. First, when using C++/CLI, "Any CPU" doesn't exist. I had to build both for x86 to get through things.

Also, though my wrapper's dependencies were satisfied, it's the wrapper's exception that is caught by the CLR so it claims that the wrapper is missing a dependency. I was actually missing a dependency for the C++ DLL my wrapper wrapped (in my case, it was just a matter of forgetting to drop SDL2.dll and OpenAL32.dll in my new "Release" configuration output folder... I'd previously only worked with the Debug configuration where I'd already dropped those DLLs.

If you're positive you've got your wrapper's dependencies worked out, I'd recommend using Dependency Walker to check out the native DLL's dependencies. You could use Assembly.GetReferencedAssemblies with an outside script/program to double-check your wrapper as well (or ILSpy: http://ilspy.net/).

Last but not least, take a look at this: http://www.codeproject.com/Articles/442784/Best-gotchas-of-Cplusplus-CLI. He details the first two recommendations I made as well as some others.

Good luck!



回答3:

One alternate root cause I've been running into quite a bit later, is that the application I'm working on uses impersonation, and the impersonated user does not have permissions to the GAC or to the folder that some dlls are in. You need to either give that user permissions, or change the way you do impersonation to load the dependencies before impersonation starts.