473,407 Members | 2,326 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

Managed C++ wrapper with abstract base return types

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

Nov 17 '05 #1
9 2388
WithPit wrote:
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; }

// ...
};
Nov 17 '05 #2
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;
};

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #3
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

"Jochen Kalmbach [MVP]" <no********************@holzma.de> skrev i
meddelandet news:eH**************@TK2MSFTNGP15.phx.gbl...
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;
};

--
Greetings
Jochen

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

Nov 17 '05 #4
Hi Tommy!
class MyClass
{
public:
...
char* myStr;
CPoint myPoint;
int myInt;
...
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>

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #5
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

"Jochen Kalmbach [MVP]" <no********************@holzma.de> skrev i
meddelandet news:uu**************@TK2MSFTNGP15.phx.gbl...
Hi Tommy!
class MyClass
{
public:
...
char* myStr;
CPoint myPoint;
int myInt;
...
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>

--
Greetings
Jochen

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

Nov 17 '05 #6
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
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


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>

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #7
> 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
{
public:
char* myStr;
CPoint myPoint;
int myInt;
CPoint getPoint() { return CPoint();}
};
#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
{
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>

--
Greetings
Jochen

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

Nov 17 '05 #8
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.

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #9
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

"WithPit" wrote:
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

Nov 17 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

33
by: Chris Capel | last post by:
What is the rationale behind the decision not to allow abstract static class members? It doesn't seem like it's a logically contradictory concept, or that the implementation would be difficult or...
6
by: Dan Sikorsky | last post by:
If we were to define all abstract methods in an abstract class, thereby making that class non-abstract, and then override the heretofore 'abstract' methods in a derived class, wouldn't that remove...
3
by: Tommy Svensson \(InfoGrafix\) | last post by:
I've been instructed to work againt a huge unmanaged C++ API from a C# application. Now, the only way, as I've understood it, is to go the Managed Extensions for C++ way. This means I have to...
3
by: WithPit | last post by:
I am trying to create an managed wrapper but have some problems with it by using abstract classes. In my unmanaged library code i had the following three classes with the following hierarchy ...
13
by: bonk | last post by:
Hello, I am trying to create a dll that internally uses managed types but exposes a plain unmanaged interface. All the managed stuff shall be "wrapped out of sight". So that I would be able to...
17
by: baibaichen | last post by:
i have written some code to verify how to disable slicing copy according C++ Gotchas item 30 the follow is my class hierarchy, and note that B is abstract class!! class B { public: explicit...
6
by: Alden Pierre | last post by:
Hello, http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7 As per the link above it's wise to have a virtual deconstructor when creating an abstract class. Here is when I'm...
7
by: jason | last post by:
In the microsoft starter kit Time Tracker application, the data access layer code consist of three cs files. DataAccessHelper.cs DataAcess.cs SQLDataAccessLayer.cs DataAcccessHelper appears...
1
by: thedbflow | last post by:
Folks, I have a bit of a quandary I was hoping for some expert guidance on. Keep in mind I am not a C++ developer, but I have worked with the language a bit. I have a native C++ API which I am...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.