Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / May 2005

Tip: Looking for answers? Try searching our database.

Managed C++ wrapper with abstract base return types

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
WithPit - 23 May 2005 08:39 GMT
I am trying to create an Managed C++ Wrapper around an unmanaged library
which contains C++ code.

Some of the unmanaged methods returns an returntype which is of the abstract
base type (for example unmanagedObject). How can i convert this to the
managed abstract basetype?

Hope somebody can help me

Thanx
Ioannis Vranos - 23 May 2005 12:38 GMT
> I am trying to create an Managed C++ Wrapper around an unmanaged library
> which contains C++ code.
>
> Some of the unmanaged methods returns an returntype which is of the abstract
> base type (for example unmanagedObject). How can i convert this to the
> managed abstract basetype?

What about something like this:

__gc class SomeClass
{
 UnmanagedObject *pobj;

 // ...

 public:

 UnmanagedObject *GetUnmanagedObject() { return pobj; }

 // ...
};
Jochen Kalmbach [MVP] - 23 May 2005 12:52 GMT
Hi WithPit!
> I am trying to create an Managed C++ Wrapper around an unmanaged library
> which contains C++ code.
>
> Some of the unmanaged methods returns an returntype which is of the abstract
> base type (for example unmanagedObject). How can i convert this to the
> managed abstract basetype?

If you really write an wrapper then your class should look like:

public __gc Wrapper : public IDisposable
{
  public:
    Wrapper() {pNative = new NativeClass;)
    int WrapperFunction1(...) {return pNative->Function1(...);}
    void WrapperFunction2(...) {return pNative->Function2(...);}
    void Dispose() (delete pNative;);
  private:
    NativeClass *pNative;
};

(Of course, sometimes you need to do some marshalling...)

And now, if it returns the object itself, you just need to create an new
instance of the Wrapper-class (and you also must be sure to call the
correctly deletefuntion):

public __gc Wrapper : public IDisposable
{
  public:
    Wrapper() {pNative = new NativeClass;)
    int WrapperFunction1(...) {return pNative->Function1(...);}
    void WrapperFunction2(...) {return pNative->Function2(...);}
    void Dispose() (delete pNative;);

    // *the following is important!*
    Wrapper *Function3 {return new Wrapper(pNative->Function3());}
  private:
    // *the following is important!*
    Wrapper(NativeClass *pRef) {pNative = pRef;}
    NativeClass *pNative;
};

Signature

Greetings
  Jochen

   My blog about Win32 and .NET
   http://blog.kalmbachnet.de/

Tommy Svensson \(InfoGrafix\) - 23 May 2005 13:45 GMT
Jochen, great and clear examples! Can you please show how to do marshalling
if function2 were to return the following native/unmanaged type:

class MyClass
{
public:
 ...
 char* myStr;
 CPoint myPoint;
 int myInt;
 ...
 CPoint getPoint();
}

Also, while at it, from the wrapper, how can you return a .NET String from
say native function4 that actually returns char*, tchar*, w_char* or
whatever?

Thx!!!

/Tommy

> Hi WithPit!
> > I am trying to create an Managed C++ Wrapper around an unmanaged library
[quoted text clipped - 38 lines]
>      NativeClass *pNative;
> };
Jochen Kalmbach [MVP] - 23 May 2005 14:03 GMT
Hi Tommy!

> class MyClass
> {
[quoted text clipped - 6 lines]
>   CPoint getPoint();
> }

Is this a native class?
Maybe you should implement CPoint as a value-type instad of a class...

> Also, while at it, from the wrapper, how can you return a .NET String from
> say native function4 that actually returns char*, tchar*, w_char* or
> whatever?

.NET only uses System::String as the representation of "strings". This
string is always UNICODE.
To convert from "char", "wchar_t" or "TCHAR" simple return the string or
pass it to the System::String-Constructor:

<code>
  System::String *GetString1()
  {
    char *szString = "Hello world1";
    return new System::String(szString);
  }
  System::String *GetString2()
  {
    wchar_t *szString = L"Hello world2";
    return new System::String(szString);
  }
  System::String *GetString3()
  {
    TCHAR *szString = _T("Hello world3");
    return new System::String(szString);
  }
</code>

Signature

Greetings
  Jochen

   My blog about Win32 and .NET
   http://blog.kalmbachnet.de/

Tommy Svensson \(InfoGrafix\) - 23 May 2005 14:28 GMT
Thx for your fast reply and thx for the System::String example!

Ok, maybe MyClass is not native but it's unmanaged and it is the actual
definition of the class, which I can't change... it's inside a third party
dll. Anyhow, I have functions in a dll API that return objects of this type,
so how can I deal with it in for example C#?

I can't do like this, right?

In C#:
""""""
using MyWrapperNS; // Access to a MyWrapper type
using MyWrapperNSInternalNativeNS; //access to MyClass

MyWrapper myW = new MyWrapper();
MyClass myClass = myWrapper.callNativeFunction1();

If not (it doesn't :)), then how do I do?

Thx again Jochen for all help,

/TOmmy

> Hi Tommy!
>
[quoted text clipped - 38 lines]
>    }
> </code>
Jochen Kalmbach [MVP] - 23 May 2005 15:25 GMT
Hi Tommy!

> Ok, maybe MyClass is not native but it's unmanaged and it is the actual
> definition of the class, which I can't change... it's inside a third party
[quoted text clipped - 7 lines]
> using MyWrapperNS; // Access to a MyWrapper type
> using MyWrapperNSInternalNativeNS; //access to MyClass

You can´t access any unmanaged object (in a good way) from a managed
language.

So for your example it looks like the following:

<code>
#pragma unmanaged
class MyClass
{
public:
  char* myStr;
  CPoint myPoint;
  int myInt;
  CPoint getPoint() { return CPoint();}
};
#pragma managed

public __gc class MyClassWrapper : public IDisposable
{
  public:
    MyClassWrapper()
    {
      pMyClass = new MyClass();
    }
    __property System::String *get_MyStr()
    {
      if (pMyClass == NULL)
        throw new System::InvalidOperationException(S"Object already
disposed!");
      if (pMyClass->myStr == NULL)
        return 0;
      return new System::String(pMyClass->myStr);
    }

    __property int get_MyInt()
    {
      if (pMyClass == NULL)
        throw new System::InvalidOperationException(S"Object already
disposed!");
      return pMyClass->myInt;
    }

    __property System::Drawing::Point get_MyPoint()
    {
      if (pMyClass == NULL)
        throw new System::InvalidOperationException(S"Object already
disposed!");
      return System::Drawing::Point(pMyClass->myPoint.x,
pMyClass->myPoint.y);
    }
    System::Drawing::Point GetPoint()
    {
      if (pMyClass == NULL)
        throw new System::InvalidOperationException(S"Object already
disposed!");
      CPoint p = pMyClass->getPoint();
      return System::Drawing::Point(p.x, p.y);
    }
    void Dispose()
    {
      Dispose(true);
    }
  private:
    ~MyClassWrapper()
    {
      Dispose(false);
    }
    void Dispose(bool disposing)
    {
      if (pMyClass != NULL)
        delete pMyClass;
      pMyClass = NULL;
      if (disposing == true)
        System::GC::SuppressFinalize(this);
    }
    MyClass *pMyClass;
};
</code>

Signature

Greetings
  Jochen

   My blog about Win32 and .NET
   http://blog.kalmbachnet.de/

Tommy Svensson \(InfoGrafix\) - 24 May 2005 10:26 GMT
> So for your example it looks like the following:
>
> <code>
> #pragma unmanaged

Hey, wait a minute... this "#pragma unmanaged" is specific for C++/CLI
right...? I only have VS 2003 with Managed Extensions for C++... or is this
valid in VS 2003 too?

> class MyClass
> {
[quoted text clipped - 5 lines]
> };
> #pragma managed

Ok, now the definition of MyClass is in the same file as my wrapper but the
fact is that the unmanaged API functions reside in a DLL (or a .lib). How
can I get access to them?

Do I need to derive from IDisposable? What happens if I don't?

Thx!!!

> public __gc class MyClassWrapper : public IDisposable
> {
[quoted text clipped - 57 lines]
> };
> </code>
Jochen Kalmbach [MVP] - 24 May 2005 10:43 GMT
Hi Tommy!

>><code>
>>#pragma unmanaged
>
> Hey, wait a minute... this "#pragma unmanaged" is specific for C++/CLI
> right...? I only have VS 2003 with Managed Extensions for C++... or is this
> valid in VS 2003 too?

It is also valid in VC2003.
By the way: You do not need to set this pragma! I just wanted to show
that this class really can be an unmanaged or native class!

> Ok, now the definition of MyClass is in the same file as my wrapper but the
> fact is that the unmanaged API functions reside in a DLL (or a .lib). How
> can I get access to them?

Äh... whyt should be the problem?
Include the h-File, and add the LIB to your linker settings.

> Do I need to derive from IDisposable? What happens if I don't?

An managed class has a non-deterministic life-time!
If you have references to native resources, then you *should* implement
the "IDisposable" pattern.
There are only two other ways to overcome this:
1. It does not matter if the native-resource will be freed from a
different thread during finalization
2. You do not allocate a native-resource in the cinstructor; instead you
allocate it on every method and destroy it before you leave the method.

Signature

Greetings
  Jochen

   My blog about Win32 and .NET
   http://blog.kalmbachnet.de/

WithPit - 27 May 2005 06:50 GMT
Thanx for all the replies but that was not my question. I will explain it a
little bit more.

In my unmanaged library code i had the following three classes with the
following hierarchy

Referenced (class)
Object (abstract class, inheriting from referenced)
Node (class, inheriting from object)

I want to make an managed wrapper for it with the same type of classes. So i
created an managed referenced class, and because this is the base class i
give it the pointer to the unmanaged object referenced.

The object class will be an managed abstract class with no constructor,
because abstract class should not have one. One of the methods of the
unmanaged class is cloneObject which should be implemented by the classes
that are inheriting of the abstract class Node. CloneObject gives as result
an value of the type Object.

So now the problem, i create an managed class Node which implements the
cloneObject method. But how to define the body of this method. Because with
not abstract classes i have created an extra constructor which get the
unmanagedobject en wrapped it. But with an abstract return type this is not
possible.

Hope this gives you more details about my question, and i hope somebody had
an solution for it.

Thanx

WithPit

> I am trying to create an Managed C++ Wrapper around an unmanaged library
> which contains C++ code.
[quoted text clipped - 6 lines]
>
> Thanx

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.