Apologize for my very basic knowledge of C++/CLI, but it has only been introduced to me recently as a necessity. I am trying to create a wrapper for an unmanaged C++ library using C++/CLI. I have followed this helpful guide and can confirm that it (somehow) does the trick. The problem I have is with C++ pointers which expose access to public classes in the unmanaged library. In my CPP library I used them to call the methods from several classes, by having access to a single point-of-entry class. In C# I can't access the methods which should be accessible via these class pointers. I am getting an error stating "the member is inaccessible due to its protection level" and the "->" pointer does not grant access to the exposed class members.
Here's what my code looks like:
UnmanagedCode::ClassA
...
// some code
...
public:
void doSomething() { ... };
ClassB* classB() { return classB.get(); };
private:
std::unique_ptr<ClassB> classB_ {};
C++/CLI wrapper
public ref class WrapperClass: public ManagedObject<UnmanagedCode::ClassA>
{
public:
WrapperClass() : ManagedObject(new UnmanagedCode::ClassA) {}; // template class code in the hyperlink
~WrapperClass() {};
void doSomething() { m_Instance->doSomething(); };
UnmanagedCode::ClassB* classB() { return m_Instance->classB(); };
};
C# program
class Program
{
static void Main(string[] args)
{
WrapperClass w = new WrapperClass();
w.doSomething(); // this works fine
w.classB(); // here is where I am getting the error
}
}
My C# knowledge, is not quite as good as my C++, just as a note. I dont quite get what you are doing here:
UnmanagedCode::ClassB* classB() { return m_Instance->classB(); };
This line returns a pointer to a ClassB object, that you retrieve in C#. This would require the ClassB to also be a managed object, as far as i know, otherwise, i dont think you can call functions on the object, without creating delegates for unsafe function pointers.
If i understand your issue correct, i think something like this, would fix your issue, in C++:
void* classB() { return static_cast<void*>(m_Instance->classB()); };
void doSomethingWithClassB(void* instance) {static_cast<ClassB*>(instance)->doSomethingWithClassB();}
and then in C#:
class Program
{
static void Main(string[] args)
{
WrapperClass w = new WrapperClass();
w.doSomething();
unsafe
{
void* classb = w.classB();
w.doSomethingWithClassB(classb);
}
}