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 2007

Tip: Looking for answers? Try searching our database.

Callback function from native C to C++\CLI using non-static member or delegates

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
smmk25@hotmail.com - 24 May 2007 06:17 GMT
Before I state the problem, I just want to let the readers know, I am
knew to C++\CLI and interop so please forgive any newbie questions.

I have a huge C library which I want to be able to use in a .NET
application and thus am looking into writing a managed C++ wrapper for
in vs2005.  Furthermore, this library has many callback hooks which
need to be implemented by the C++ wrapper.

These callback functions are declared as "extern C __cdecl"  which I
am still trying to understand why. However, that is not the main
concern.  My main question is , is there any possible way to implement
the callback function to point to a non-static member function rather
than a static function ?

The reason being is that I need to be able to work with multiple
instances of this wrapper, and if the callback functions are limited
to static only, then obviously I would not be able to do this.

I have seen some examples on the web, but those mainly deal with
Windows API's, and don't seem to address this sort of issue.

I would be interested to know if this is possible using delegates, or
whether it is even possible to have the C callback function call a non-
static member function of my C++ wrapper.

Thanks in advance for our help
SvenC - 24 May 2007 07:11 GMT
> I have a huge C library which I want to be able to use in a .NET
> application and thus am looking into writing a managed C++ wrapper for
[quoted text clipped - 3 lines]
> These callback functions are declared as "extern C __cdecl"  which I
> am still trying to understand why.

Well, you have to choose a calling convention. extern C controls the name
mangling which mangles less than C++ exports.

> concern.  My main question is , is there any possible way to implement
> the callback function to point to a non-static member function rather
> than a static function ?

No, because that defines how the function call is coded when it comes to
machine code. A pointer to a class member function typically needs more
information (the this pointer of the instance e.g.) and more code for being
executed, so you cannot hand this information to a function pointer of the
above type.

> The reason being is that I need to be able to work with multiple
> instances of this wrapper, and if the callback functions are limited
> to static only, then obviously I would not be able to do this.

The only way I see would be that those callbacks would pass you a unique
value which you can control when you initialize a callback. Some sort of
cookie which lets you identify who initiated the callback when you are
called back. But that of course would only work if that library was designed
in that way.

> I have seen some examples on the web, but those mainly deal with
> Windows API's, and don't seem to address this sort of issue.

Sometimes the windows Api uses an LPVOID param which can be seen as such a
cookie. Was it that what you saw?

> I would be interested to know if this is possible using delegates, or

Don't think so.

> whether it is even possible to have the C callback function call a
> non- static member function of my C++ wrapper.

Don't think so either.

--
SvenC
Carl Daniel [VC++ MVP] - 24 May 2007 14:18 GMT
> Before I state the problem, I just want to let the readers know, I am
> knew to C++\CLI and interop so please forgive any newbie questions.
[quoted text clipped - 20 lines]
> whether it is even possible to have the C callback function call a
> non- static member function of my C++ wrapper.

There are basically two approaches to getting into a member function of some
class instance from a simple function pointer callback.

1. The API that uses the callback includes a "context" parameter of
sufficient size to hold a pointer.  For example, you might have declarations
something like this:

void RegisterCallback(int (*cbfn)(int p1,int p2,void* context), void*
context);

Here, a hypothetical callback registration function accepts a pointer to a
function and an additional void* argument.  When the callback is called, the
context argument of the register function is passed to the context parameter
of the callback function.  Many Windows APIs that use callbacks use this
pattern.

In a case like this, you can write a small "trampoline function" that makes
the jump from a simple function to a member function:

class SomeClass(
{
   // ...
   int Callback(int p1, int p2) { ... }
};

int CallbackTrampoline(int p1, int p2, void* context)
{
   return static_cast<SomeClass*>(context)->Callback(p1,p2);
}

2. The API doesn't provide a context object (or "cookie").

In this case, the API was simply not designed to support object-oriented
usage, so your only recourse for getting the callback to call into a member
function involves dynamic code generation.  Basically, you have to write
code that generates the above trampoline function at runtime, burning the
address of the object into the function.  Such code is subtle and
non-portable, but the technique is used more than one might guess.

-cd
Ben Voigt - 24 May 2007 16:08 GMT
>> Before I state the problem, I just want to let the readers know, I am
>> knew to C++\CLI and interop so please forgive any newbie questions.
[quoted text clipped - 59 lines]
> burning the address of the object into the function.  Such code is subtle
> and non-portable, but the technique is used more than one might guess.

I believe that .NET makes this very easy, with
Marshal.GetFunctionPointerForDelegate, since the JIT habitually does dynamic
code generation.

> -cd
rawhahs - 24 May 2007 16:46 GMT
> > smm...@hotmail.com wrote:
> >> Before I state the problem, I just want to let the readers know, I am
[quoted text clipped - 70 lines]
>
> - Show quoted text -

Ben, Carl,  Thanks for your replies.  Ben is it possible for you to
put up an example of how to do this using delegates ?  I have seen
some posts which do claim that this is possible to do.

Carl,

You are correct the API is not changeable and i am not sure if it was
meant for object oriented programming.  Therefore I am not able to
modify it at all, and only have the .h to work with.

Thanks to both of you for your help.
Ben Voigt - 24 May 2007 18:36 GMT
> Ben, Carl,  Thanks for your replies.  Ben is it possible for you to
> put up an example of how to do this using delegates ?  I have seen
> some posts which do claim that this is possible to do.

http://msdn2.microsoft.com/en-us/library/ms776420.aspx

> Carl,
>
[quoted text clipped - 3 lines]
>
> Thanks to both of you for your help.
Carl Daniel [VC++ MVP] - 25 May 2007 05:02 GMT
> "Carl Daniel [VC++ MVP]"
>> In this case, the API was simply not designed to support
[quoted text clipped - 8 lines]
> Marshal.GetFunctionPointerForDelegate, since the JIT habitually does
> dynamic code generation.

Yes - I thought there was a handy .NET shortcut for it, but didn't have any
handy .NET references at hand when I was writing.  Sure makes it a lot
easier than the all-native solutions turn out to be!

-cd

Rate this thread:







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.