0

I have written two managed C++ wrappers for native C++ classes and I need a unmanaged object of native Class B as a return param in function of managed Wrapper A that construct native Class A!

Example:

// Wrapper A

WrapperA::WrapperA(ClassB *classB)
{
    ClassA *classA = new ClassA(classB);
    ...
}

// native c++
ClassA::ClassA(ClassB *classB)
{
    m_classB = classB; // ClassB *m_classB; in .h
    ...
}

// Wrapper B

ClassB* WrapperB::GetNativeClassB()
{
    return m_classB; // ClassB *m_classB; in .h
}


// in C#
...
WrapperB wrapperB = new WrapperB();

unsafe // need for C++ pointer
{
WrapperA wrapperA = new WrapperA(wrapperB.GetNativeClassB() ); 
// Error: is inaccessible due to its protection level 
// -> is set to public
}
...

Is there a better way without unsafe and why I get an access error ???

Thank you in advance!

greets leon22

leon22
  • 5,280
  • 19
  • 62
  • 100

2 Answers2

1
  1. Protection level: i'm sure you have public defined, but what about the dll containing the symbol? Are you sure you have the last release?

  2. Unsafe: in order to use/wrap unsafe/native code as C++, the best option it is to use C++/CLI (ex Managed C++), provided starting from the Visual Studio 2005 release. just define a ref class that wraps your native/unmanaged class, that one will be directly accessible from managed code, as C#. Hint to start with Visual Studio: open a new dll CLR project from the Visual C++ section;

C++/CLI is the best solution in my opinion

Marcello Faga
  • 1,134
  • 8
  • 12
  • I'm using the classB object already in WrapperB (loading from a dll with GetProcAddress) and it works fine, but returning the object to C# and bypass to WrapperA does not work (due the protection error) – leon22 Jul 12 '11 at 12:26
  • And sure the wrappers are written in C++/CLI – leon22 Jul 12 '11 at 12:26
  • I think you do not write properly your C++/CLI wrapper classes, because you use unsafe pointer in your wrapper interface (WrapperA(ClassB *classB) ), consequently you need to use the unsafe block. exemple for the contructor of wrapperA-> WrapperA::WrapperA(WrapperB ^classB). use the native pointers only inside the wrapper class – Marcello Faga Jul 12 '11 at 12:36
  • I have tested on other way: give the WrapperB with managed ^ as param to WrapperA and then I call wrapperB->GetNativeClassB() -> error: error C3767: candidate function(s) not accessible (method and class are public) I don't understand this (the wrappers are included per add reference in C#) – leon22 Jul 12 '11 at 13:26
  • Ok, the last one, i hope it can help you. have you already tried #pragma make_public(ClassB)? http://msdn.microsoft.com/en-us/library/ms235607%28VS.80%29.aspx. – Marcello Faga Jul 12 '11 at 13:41
  • Yes. I get error that this directive is only for native types. I get the object to return from a native C++ dll (with GetProcAddress and extern "C" _declspec(dllexport) ...) are the object then private? (I have read with /clr compilation native types are now private by default) any suggestions?! – leon22 Jul 12 '11 at 15:06
  • You're right, what i might do in your place it is to wrap any method of the native class you have to use, then use just the wrapped methods inside the other managed ref class. the native reference must be private of the ref class who wraps that. What do you think? Otherwise you can build just one wrap class which includes all the two unmanaged classes. It depends... – Marcello Faga Jul 12 '11 at 15:24
  • @leon22 let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/1377/discussion-between-marcello-faga-and-leon22) – Marcello Faga Jul 12 '11 at 15:24
0

Solution from: Pass a C++/CLI wrapper of a native type to another C++/CLI assembly

// in WrapperB
property IntPtr _classB 
{
    IntPtr get() { return IntPtr(classB); }
}

// in WrapperA
ClassB *classB = static_cast<ClassB*>(wrapperB->_classB.ToPointer());
// ... do something ...
Community
  • 1
  • 1
leon22
  • 5,280
  • 19
  • 62
  • 100