[.net] C++/CLI Wrappers

Started by
3 comments, last by Washu 18 years, 1 month ago
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.
Advertisement
*coughs*
You could also use the MarshalAsAttribute, see: Custom Marshalling.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Quote:Original post by Washu
*coughs*
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!
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...
Yeah, it will most likely have to.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

This topic is closed to new replies.

Advertisement