G
Guest
I need to write a C# application that uses unmanaged C++ code. I created a
C++/CLI wrapper to C++ code and encountered the following problem. Any time I
try to instantiate a wrapper in C# application the program crashes with an
error
"An unhandled exception of type 'System.IO.FileNotFoundException' occurred
in mscorlib.dll, Additional information: The specified module could not be
found. (Exception from HRESULT: 0x8007007E)". C# application has a reference
only to the wrapper and the wrapper has a reference to unmanaged dll. Similar
application written in C++/CLI gives exactly the same error if it has a
reference only to the wrapper namespace. In case of C++/CLI application,
VS2005 allows to add a reference to unmanaged dll and then the application
works OK.
I have seen an example of managed C++ wrapper that is virtual identical to
the code below and is claimed to work with C#
(http://www.ondotnet.com/lpt/a/4731)
Cannot figure out what is the problem with my code.
Here is the code
//CppLib.h
#ifndef _CPPLIB_EXPORT_IMPORT
#ifdef _CPPLIB_EXPORT
#define _CPPLIB_EXPORT_IMPORT __declspec(dllexport)
#else
#define _CPPLIB_EXPORT_IMPORT __declspec(dllimport)
#endif
#endif
class _CPPLIB_EXPORT_IMPORT CCppLib
{
double _a;
double _b;
double _c;
public:
CCppLib(double a, double b, double c);
~CCppLib(){};
bool IsValid();
};
//CppLib.cpp
CCppLib::CCppLib(double a, double b, double c)
{
_a = a;
_b = b;
_c = c;
}
bool CCppLib::IsValid()
{
return (_a + _b > _c && _a + _c > _b && _b + _c > _a );
}
//CLRWrapper.h
#pragma once
#include "..\\CppLib\\CppLib.h"
using namespace System;
namespace CLRWrapper
{
public ref class Triangle
{
CCppLib* _CppLib;
public:
Triangle()
{
_CppLib = new CCppLib();
}
Triangle(double a, double b, double c)
{
_CppLib = new CCppLib(a, b, c);
}
~Triangle()
{
this->!Triangle();
}
!Triangle()
{
if (_CppLib != NULL)
delete _CppLib;
_CppLib = 0;
}
CCppLib* GetCppLib() { return _CppLib;}
bool IsValid()
{
if (_CppLib != NULL)
return _CppLib->IsValid();
return false;
}
};
}
// CLRTest.cpp C++/CLI test application
using namespace System;
using namespace CLRWrapper;
int main(array<System::String ^> ^args)
{
Triangle^ tr = gcnew Triangle(1, 2, 3);
Console::WriteLine(tr->IsValid());
return 0;
}
//Program.cs C# test application
using System;
using System.Collections.Generic;
using System.Text;
using CLRWrapper;
namespace TestTriangle
{
class Program
{
static void Main(string[] args)
{
Triangle tr = new Triangle(0.1, 0.2, 0.3);
Console.WriteLine(tr.IsValid());
}
}
}
C++/CLI wrapper to C++ code and encountered the following problem. Any time I
try to instantiate a wrapper in C# application the program crashes with an
error
"An unhandled exception of type 'System.IO.FileNotFoundException' occurred
in mscorlib.dll, Additional information: The specified module could not be
found. (Exception from HRESULT: 0x8007007E)". C# application has a reference
only to the wrapper and the wrapper has a reference to unmanaged dll. Similar
application written in C++/CLI gives exactly the same error if it has a
reference only to the wrapper namespace. In case of C++/CLI application,
VS2005 allows to add a reference to unmanaged dll and then the application
works OK.
I have seen an example of managed C++ wrapper that is virtual identical to
the code below and is claimed to work with C#
(http://www.ondotnet.com/lpt/a/4731)
Cannot figure out what is the problem with my code.
Here is the code
//CppLib.h
#ifndef _CPPLIB_EXPORT_IMPORT
#ifdef _CPPLIB_EXPORT
#define _CPPLIB_EXPORT_IMPORT __declspec(dllexport)
#else
#define _CPPLIB_EXPORT_IMPORT __declspec(dllimport)
#endif
#endif
class _CPPLIB_EXPORT_IMPORT CCppLib
{
double _a;
double _b;
double _c;
public:
CCppLib(double a, double b, double c);
~CCppLib(){};
bool IsValid();
};
//CppLib.cpp
CCppLib::CCppLib(double a, double b, double c)
{
_a = a;
_b = b;
_c = c;
}
bool CCppLib::IsValid()
{
return (_a + _b > _c && _a + _c > _b && _b + _c > _a );
}
//CLRWrapper.h
#pragma once
#include "..\\CppLib\\CppLib.h"
using namespace System;
namespace CLRWrapper
{
public ref class Triangle
{
CCppLib* _CppLib;
public:
Triangle()
{
_CppLib = new CCppLib();
}
Triangle(double a, double b, double c)
{
_CppLib = new CCppLib(a, b, c);
}
~Triangle()
{
this->!Triangle();
}
!Triangle()
{
if (_CppLib != NULL)
delete _CppLib;
_CppLib = 0;
}
CCppLib* GetCppLib() { return _CppLib;}
bool IsValid()
{
if (_CppLib != NULL)
return _CppLib->IsValid();
return false;
}
};
}
// CLRTest.cpp C++/CLI test application
using namespace System;
using namespace CLRWrapper;
int main(array<System::String ^> ^args)
{
Triangle^ tr = gcnew Triangle(1, 2, 3);
Console::WriteLine(tr->IsValid());
return 0;
}
//Program.cs C# test application
using System;
using System.Collections.Generic;
using System.Text;
using CLRWrapper;
namespace TestTriangle
{
class Program
{
static void Main(string[] args)
{
Triangle tr = new Triangle(0.1, 0.2, 0.3);
Console.WriteLine(tr.IsValid());
}
}
}