472,353 Members | 1,488 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,353 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 2267
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,...
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'...
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...
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...
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...
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...
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...
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...
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...
1
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
0
jalbright99669
by: jalbright99669 | last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
0
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. ...
2
by: Matthew3360 | last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...
0
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand....

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.