473,881 Members | 1,570 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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

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

May 24 '07 #1
6 7687
sm****@hotmail. com wrote:
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.
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

May 24 '07 #2
sm****@hotmail. com wrote:
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.
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 RegisterCallbac k(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 CallbackTrampol ine(int p1, int p2, void* context)
{
return static_cast<Som eClass*>(contex t)->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
May 24 '07 #3

"Carl Daniel [VC++ MVP]" <cp************ *************** **@mvps.org.nos pam>
wrote in message news:eu******** *****@TK2MSFTNG P06.phx.gbl...
sm****@hotmail. com wrote:
>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.

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 RegisterCallbac k(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 CallbackTrampol ine(int p1, int p2, void* context)
{
return static_cast<Som eClass*>(contex t)->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.
I believe that .NET makes this very easy, with
Marshal.GetFunc tionPointerForD elegate, since the JIT habitually does dynamic
code generation.
>
-cd


May 24 '07 #4
On May 24, 11:08 am, "Ben Voigt" <r...@nospam.no spamwrote:
"Carl Daniel [VC++ MVP]" <cpdaniel_remov e_this_and_nos. ..@mvps.org.nos pam>
wrote in messagenews:eu* ************@TK 2MSFTNGP06.phx. gbl...


smm...@hotmail. com wrote:
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.
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 RegisterCallbac k(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 CallbackTrampol ine(int p1, int p2, void* context)
{
return static_cast<Som eClass*>(contex t)->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.

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


-cd- Hide quoted text -

- Show quoted text -- Hide quoted text -

- 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.

May 24 '07 #5
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,

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.

May 24 '07 #6
Ben Voigt wrote:
"Carl Daniel [VC++ MVP]"
>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.

I believe that .NET makes this very easy, with
Marshal.GetFunc tionPointerForD elegate, 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
May 25 '07 #7

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

Similar topics

8
572
by: kurtcobain1978 | last post by:
-------------------------------------------------------------------------------- I need to do the exactly same thing in VB.NET. Load a unmanaged C DLL dynamically and then call a function in which I pass the callback function as an argument. My C function being called callback as type _cdecl. Does anybody have any ideas?
0
327
by: Lonewolf | last post by:
Hi, I'm not sure if this has been asked before so please pardon me if this is a repeated question. Basically I have some performance critical directshow codes which is implemented in native, unmanaged C++. I have written a managed wrapper for it using C++/CLI. problem comes when I try to pass a C# string over to the DLL via C++/CLO. Basically I have a textbox in the C# GUI, and I declared my C++/CLI property as follows. C++/CLI property...
0
1069
by: draskin | last post by:
Hello, I have the following situation: - Text.exe creates a new AppDomain - Test.exe loads mixed mode assembly in a non-default AppDomain - Test.exe calls connect to a TCP/IP socket server which calls into native code to actually create a TCP/IP socket connection - Test code sets up a listener using the mixed mode assembly to be notified asynchronously (i.e. on a different thread) of events. The listener is held onto by a managed...
12
12567
by: DaTurk | last post by:
Hi, I have a rather interesting problem. I have a unmanged c++ class which needs to communicate information to managed c++ via callbacks, with a layer of c# on top of the managed c++ ultimatley retreiving the data. Presently all of the c++ code is still in .NET 1.1, so we're using a _nogc bridge class wrapped in a _gc c++ class in order to facilitate this interop. But we've converted everything not c++ to .NET 2.0 and would love to
3
3876
by: Builder | last post by:
Hello, I created a DirectShow filter which detects faces from video. Filter exposes interface, which enables to set a callback, which is called when a face is detected. I made an application in C# which creates a DirectShow graph with mentioned face detector filter and calls its interface. Excerpt of the face detector interface declaration is as follows (method SetCallback is important):
0
1405
by: DavidT | last post by:
Hello, at first, exuse if the following question is simple to solve, but i normaly coding with C# and now have to use C++/CLI for one project. My Problem is that i have to use a native c++ sdk to read pictures from ip cameras. I get the native c++ decoder worked so far and now try to send callbacks from unmanaged to managed code, to signal wenn a picture is fully received. To get a first view on that area i implemented a little test...
0
1444
by: nabil035 | last post by:
I explain exactly what I want to do: write a callback function in a C++/CLI application this application imports function from a native DLL call this function from the DLL and return the results to the application Can Anyone help with the simplest example, please!
0
1074
by: DaTurk | last post by:
Hi, I'm writing an application that has a native c++ layer, and a CLi/C++ layer above it. Above the CLi layer will be C# but that's not relavent to this post. My question has to do with communicating between the native layer to the CLi layer. Typically how I do this is this ... **CLi/C++ Layer**
1
1610
by: DaTurk | last post by:
Sorry, some how I clicked post before I finished. Hi, I'm writing an application that has a native c++ layer, and a CLi/C++ layer above it. Above the CLi layer will be C# but that's not relavent to this post. My question has to do with communicating between the native layer to the CLi layer. Typically how I do this is this ...
1
1614
by: DaTurk | last post by:
Hi, I'm writing an application that has a native c++ layer, and a CLi/C++ layer above it. Above the CLi layer will be C# but that's not relavent to this post. My question has to do with communicating between the native layer to the CLi layer. Typically how I do this is this ...
0
9776
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11096
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10716
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10400
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7953
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5780
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5976
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4597
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3223
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.