1 Attachment(s)
Using C++ classes in C# with C++/CLI
1. Constructor and Destructor
Code:
//.h
public ref class WrapperLibrary
{
public:
WrapperLibrary();
!WrapperLibrary();
~WrapperLibrary();
internal:
CCppLibrary *u_cppLibrary;
};
Code:
//.cpp
WrapperLibrary::WrapperLibrary()
{
u_cppLibrary = new CCppLibrary();
}
WrapperLibrary::!WrapperLibrary()
{
delete u_cppLibrary;
}
WrapperLibrary::~WrapperLibrary()
{
this->!WrapperLibrary();
}
2. Inheritance
Code:
//.h
public ref class WrapperLibrary
{
// ...
internal:
WrapperLibrary(CCppLibrary *u_cppLibrary);
CCppLibrary *u_cppLibrary;
};
public ref class ChildWrapper : WrapperLibrary
{
public:
ChildWrapper();
};
Code:
//.cpp
WrapperLibrary::WrapperLibrary(CCppLibrary *u_cppLibrary)
{
this->u_cppLibrary = u_cppLibrary;
}
ChildWrapper::ChildWrapper()
: WrapperLibrary(new CChildCpp())
{
}
3. String Argument
Code:
//.cpp
String ^WrapperLibrary::AppendHello(String ^str)
{
msclr::interop::marshal_context context;
const char *u_str = context.marshal_as<const char *>(str);
std::string result = u_cppLibrary->AppendHello(u_str);
String ^ret = context.marshal_as<String ^>(result);
return ret;
}
4. Function Pointer Argument
Code:
//.h
// ...
using namespace System::Runtime::InteropServices;
// ...
[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
public delegate void Callable();
// ...
public ref class WrapperLibrary
{
// ...
public:
void Call(Callable ^callable);
// ...
};
Code:
//.cpp
void WrapperLibrary::Call(Callable ^callable)
{
void (*u_callable)() = callable == nullptr ? NULL : (void (*)()) Marshal::GetFunctionPointerForDelegate(callable).ToPointer();
u_cppLibrary->Call(u_callable);
}
5. Variable Argument Function
Code:
//.cpp
struct FakeValist
{
// NOTE : the number of arguments is limited
static const int COUNT = 100;
double list[COUNT];
};
void GetNumbers(FakeValist *fakeValist, ...array<double> ^numbers)
{
int count = numbers->GetLength(0);
for (int i = 0; i < count; i++)
{
fakeValist->list[i] = numbers[i];
}
}
// ...
double WrapperLibrary::Average(...array<double> ^numbers)
{
int count = numbers->GetLength(0);
FakeValist u_numbers;
GetNumbers(&u_numbers, numbers);
double ret = u_cppLibrary->Average(count, u_numbers);
return ret;
}
5-1. Variable Argument Function ( String Formatting )
Code:
//.cpp
void WrapperLibrary::Printf(String ^format, ...array<Object ^> ^args)
{
msclr::interop::marshal_context context;
String ^formatted = String::Format(format, args);
const char *u_formatted = context.marshal_as<const char *>(formatted);
u_cppLibrary->Printf("%s", u_formatted);
}
6. Export Unmanaged Member
Code:
//.h
//...
class CCppLibrary;
#pragma make_public(CCppLibrary)
//...
public ref class WrapperLibrary
{
//...
public:
WrapperLibrary(CCppLibrary *u_cppLibrary); // Used in OtherCliLibrary. Turned private if 'make_public' not exist
//...