Sign in to follow this  

[.net] C++/CLI Wrappers

Recommended Posts

This is undoubtedly the first in a million posts on this subject, so I apologise ;) I've set about learning more about .NET, specifically C# and C++/CLI. I decided that a decent way to learn is to throw myself in at the deep end (as it were) and attempt to tackle a managed wrapper for a library that I use often, GameMonkey Script. Unlike a lot of libraries there is no DLL interface and absolutely no provision for C users, so the 'simple' PInvoke wrappers don't seem applicable here. As such, I'm looking at writing a C++/CLI wrapper for the basic functionality of the library which will allow me to at least execute scripts and to some extent bind CLI types and functions (isn't this really what a script language is about :P). So far I've managed to wrap a few of the methods, specifically those that deal with executing strings as scripts and one that registers a managed delegate as a function to be called by the script engine. However in doing so I've encountered a few difficulties (as you can imagine)... The main class gmMachine has a basic GameMonkey.Machine CLI wrapper class which is fine. The gmThread class which is used in all function callbacks is a different story. What I'd like is a delegate for a function callback is to look like this: public delegate int FunctionCallback( Thread ^a_thread ); This would allow me to directly act upon methods in my managed Thread class (which wraps gmThread, another native class). However, the C callback is specificed as such: int (*CFunction)( gmThread *a_thread ); In order to allow me to wrap this I've had to declare my delegate as: public delegate int FunctionCallback( IntPtr a_thread );. In order to use the managed GameMonkey.Thread class I have to provide myself an IntPtr constructor to initialise the gmThread *m_thread member (private) which is the actual workhorse of th class. Because of this, my C# (or otherwise) delegates all have to do the following:
public static int MyFunction( IntPtr a_thread )
  GameMonkey.Thread thread = new GameMonkey.Thread( a_thread );
  return thread.DoSomethingOnTheManagedWrapper();
This all seems pretty fugly to me. Is there anyway that I could effectively wrap (or even better AVOID) this construction of a Thread object to maintain my delegate int Blah( GameMonkey.Thread a_thread ); specification? Note, I'd also like to avoid having to allow for an IntPtr constructor on my wrapped classs to say "here, initialise this with this pointer", but I don't know if I can. Any help from you gurus out there will be most appreciated.

Share this post

Link to post
Share on other sites
Original post by Washu
You could also use the MarshalAsAttribute, see: Custom Marshalling.

I've actually been using your journal as one of my primary resources to date but I've failed to see how I can avoid this current issue. I'll take a look at how to use this attribute, but it seems all the examples around are for C#/VB.NET and not C++/CLI :(

Edit: You added a sneaky link, you cad! I'll investigate =) Thanks, Sir!

Share this post

Link to post
Share on other sites
Washu, you're a tentacled genius. The custom marshaller works perfectly, thanks!

Does this mean that my managed classes will all have to take an IntPtr as a constructor parameter if I wish to initialise the unmanaged version stored in my managed class? It's not a /huge/ problem if I have to though...

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this