Quantcast

Monday, September 8, 2008

Fixing Visual Studio Run-Time Error R6034

THE PROBLEM

As of Visual Studio 2005, you are required to associate a manifest with any DLL having implicit dependencies. If you do not, LoadLibrary() will throw a runtime error R6034.


DEPENDENCIES

Implicit dependencies are any dynamic libraries that must be loaded before your EXE or DLL (henceforth known as "module") may load. For example, if you link against the Runtime DLLs (msvcr*.dll, msvcp*.dll) then your module is implicitly dependant on them. If you specify any libraries in "Linker -> Input" then your module is implicitly dependant on them. Your module's manifest must specify the names and versions of all these implicit dependencies.

Explicit dependencies, loaded by your explicit calls to LoadLibrary(), do not have to show up in the module's manifest.

HOW DOES THIS AFFECT JAVA?

When you invoke System.loadLibrary(), Java invokes LoadLibrary() under the hood. java.exe is linked statically against the runtime libraries, so it doesn't need a manifest, but any libraries it loads do need one. To reiterate, all JNI libraries must have a manifest for their implicit dependencies.

There are two kinds of manifests: internal or external. External manifest files sit alongside your library. Internal manifests are embedded as resources directly in your module. Manifests describe the location and version of assemblies (group of libraries). Private assemblies reside in the application directory (similar to a private JRE) while public assemblies are shared by multiple applications (similar to a public JRE).



PRIVATE ASSEMBLIES

Installing shared assemblies requires administrator privileges so I'll discuss private assemblies first. Here is how it works...

  1. Pick a directory under "C:\Program Files\Microsoft Visual Studio 9.0\VC\redist". In my case this is "x86\Microsoft.VC90.CRT" (32-bit, runtime libraries)
  2. Copy any implicit dependencies along with the manifest file into your application directory. In my case I copy msvcr90.dll, msvcp90.dll and Microsoft.VC90.CRT.manifest
  3. You're done

When your module invokes LoadLibrary("foo.dll") it will look for an embedded manifest in the DLL. If none is found, it will look for an external file "foo.dll.manifest". The manifest will detail any implicit dependencies, such as msvcr90.dll. Your module manifest contains an implicit dependency on the Microsoft CRT manifest file, so do not remove it. I haven't yet found a way to ship private assemblies without this manifest file, which seems to be the only way that Webstart applications can work (aside from static linking).



SHARED ASSEMBLIES

  1. Download shared assemblies for x86, x64 or IA64 onto the user's machine
  2. Run the installer interactively or silently
  3. You're done

If you want to get fancy, check whether the user already has a manifest installed before step 1 to avoid unnecessary downloads.



REFERENCES

C Run-Time Error R6034
Visual C++ Libraries as Shared Side-by-Side Assemblies
How to: Deploy using XCopy
Impossible to use VS2005 with Java?

2 comments:

psykoprogrammer said...

This is an interesting, and rather frustrating problem. I am attempting to wrap a 3rd party vendor's C++ API in Java, and have tried both JNA and JNI, to no avail. I have manifest files from my JNI C++ DLL, I tried the one that comes with the VC++ 2008 runtime redistributable, and no love. Are there any other tricks to this crazy puzzle?

Gili said...

psykoprogrammer,

Please post more details about your problem. Also, I would recommend trying to get this working without Java first (just one C++ library loading another) before adding JNI on top.