0

I'm in the situation described here.

Where I have three classes:

  • TestLib: which is the native one;
  • AdapterClass: which holds the managed reference;
  • WrapperClass: which wraps the adapter;

AdapterClass.h

#pragma once

#include <vcclr.h>

#using <mscorlib.dll>

class AdapterClass {
public:
  AdapterClass() {
    m_ManagedObj = gcnew(Client);
  }

private:
  gcroot<Client^> m_ManagedObj;
};

WrapperClass.h

class AdapterClass;

class WrapperClass
{
public:
  WrapperClass() {
    m_pAdapter = new AdapterClass();
  }

private:
  AdapterClass *m_pAdapter;

}

TestLib.h

#pragma once

#include "stdafx.h"
#include "NativeSDK.h"

#include "WrapperClass.h"

class TestLib : public INativeSDK {
public:
  // ... code ...

private:
  WrapperClass ManagedObj;
}

The settings are:

  • Project Setting : No Support for CLR
  • TestLib.cpp : No Support for CLR
  • WrapperClass.cpp : /clr
  • AdapterClass.cpp : /clr

Now, when I run it (on VS2013) I get the following exception when I step into TestProject constructor:

  KernelBase.dll!_RaiseException@16()  + 0x58 bytes 
  clr.dll!RaiseTheExceptionInternalOnly()  + 0x143 bytes    
  clr.dll!UnwindAndContinueRethrowHelperAfterCatch()  + 0x72 bytes  
  clr.dll!CEEInfo::resolveToken()  + 0x1f9dbf bytes 
  clrjit.dll!Compiler::impResolveToken()  + 0x3a bytes  
  clrjit.dll!Compiler::impImportBlockCode()  + 0x2703c bytes    
  clrjit.dll!Compiler::impImportBlock()  + 0x55 bytes   
  clrjit.dll!Compiler::impImport()  + 0x167 bytes   
  clrjit.dll!Compiler::compCompile()  + 0x47 bytes  
  clrjit.dll!Compiler::compCompileHelper()  + 0x1f0 bytes   
  clrjit.dll!Compiler::compCompile()  + 0x104 bytes 
  clrjit.dll!jitNativeCode()  - 0x11eb bytes    
  clrjit.dll!CILJit::compileMethod()  + 0x25 bytes  
  clr.dll!invokeCompileMethodHelper()  + 0x41 bytes 
  clr.dll!invokeCompileMethod()  + 0x31 bytes   
  clr.dll!CallCompileMethodWithSEHWrapper()  + 0x2a bytes   
  clr.dll!UnsafeJitFunction()  + 0x220 bytes    
  clr.dll!MethodDesc::MakeJitWorker()  + 0x19f bytes    
  clr.dll!MethodDesc::DoPrestub()  + 0x2d0a0 bytes  
  clr.dll!_PreStubWorker@4()  + 0xbd bytes  
  clr.dll!_ThePreStub@0()  + 0x16 bytes 
  002a177f()    
  00246550()    
>   TestLib.dll!CTestLib::CTestLib()  Line 33 + 0x2e bytes  C++

Where I wrong?

Regards.

<<<<<<< EDIT >>>>>>>>

After the Hans suggestion, I used Fuslogvw.exe and I found that the problem is (I think) a version mismatch. Looking into the tool log I see:

REG: l'associazione ha origine nel contesto di caricamento di default.
REG: utilizzo del file di configurazione dell'applicazione: D:\src\TEST_SVR\bin\TestSvrd.exe.Config
REG: utilizzo del file di configurazione host: 
REG: utilizzo del file di configurazione computer da C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
REG: riferimento post-criteri: NS.Enterprise.ClientAPI, Version=3.5.0.40, Culture=neutral, PublicKeyToken=5fc871ad184a138c
REG: ricerca nella cache globale (GAC) non riuscita.
REG: tentativo di download del nuovo URL file:///D:/src/TEST_SVR/bin/NS.Enterprise.ClientAPI.DLL.
REG: download dell'assembly completato. Tentativo di installazione del file: D:\src\TEST_SVR\bin\NS.Enterprise.ClientAPI.dll
REG: ingresso nella fase di installazione relativa all'esecuzione dall'origine.
REG: nome assembly: NS.Enterprise.ClientAPI, Version=4.0.3.169, Culture=neutral, PublicKeyToken=5fc871ad184a138c
AVV: errata corrispondenza dal confronto con il nome dell'assembly: numero di versione principale
ERR: il riferimento all'assembly non corrisponde alla definizione di assembly trovata.
ERR: fase dell'installazione Esegui da origine non riuscita con hr = 0x80131040.
ERR: impossibile completare l'installazione dell'assembly (hr = 0x80131040). Sondaggio terminato.

Which is in italian but, substantially, means that it search for the NS.Enterprise.ClientAPI, Version=3.5.0.40 while the assemply on the disk is Version=4.0.3.169

So my question is:

Since in the Mixed DLL project I don't have specified the assembly version but I only have imported them:

#using <mscorlib.dll>
#using <NS.Enterprise.ClientAPI.dll>
#using <NS.Enterprise.Objects.dll>
#using <NS.Shared.dll>

how can I "adjust" this mismatch?

Community
  • 1
  • 1
Barzo
  • 1,039
  • 1
  • 11
  • 37
  • Diagnosing managed exceptions gets to be difficult when you call managed code from native C++. You are looking at the bowels of the jitter, trying to compile a managed method. And not finding an excepted type or method. Tends to be a DLL Hell problem. Try using a managed debugger so you'll have a decent exception to look at. And consider unit-testing the Client class first with a managed test program. – Hans Passant Feb 20 '14 at 14:54
  • Thanks a lot #hans-passant, in fact I suspect that it's simply a path problem, because I get: "TestSvrd.exe: Microsoft C++ exception: EEFileLoadException". What I don't understand is why. My DLL is loaded at runtime (with LoadLibrary) from the exe and it is in the same directory (with all other managed DLL needed). – Barzo Feb 20 '14 at 15:01
  • Sounded to me like you don't have an EXE but use some kind of unit test runner. The CLR is going to try to find the assembly in the same directory as the test runner. After checking the GAC. Probably in neither so, yes, a file-not-found error is likely. – Hans Passant Feb 20 '14 at 15:05
  • The VS solution is composed by a Win32 exe and the native wrapper library (as I said, loaded at runtime). The outputs are copied in the same directory and in this directory there are also all the Assemblies used. Is there a way to know where the CLR looks for the assemblies? – Barzo Feb 20 '14 at 15:31
  • 1
    Use Fuslogvw.exe to troubleshoot assembly resolution problems. – Hans Passant Feb 20 '14 at 15:32

0 Answers0