Adapting a C-style callback mechanism to C++

I'm using a C API (it's actually Spidermonkey's jsapi) with which I
can register callback functions:

void registerCallback(const char * name, CStyleFunctionPtr callback);

I'm trying to wrap and abstract away this API from my users by
offering a pure C++ interface, in which users could implement callback
via functions objects, or something similar. e.g.:

struct FooCallback : public CallbackFunction
{
	virtual void run() { /* ... /* }
}

void registerCppCallback(CallbackFunction * pCB);

You get the point. This way my callbacks have state, I don't need to
mess around with function pointers, my users don't have to even
#include the C-API's headers and I can translate their arguments from
the underlying API's C types to their equivalent STL classes.

My plan was to implement this by creating one "master" callback the C-
way and have it act as a dispatcher to the actual callback
implementations in C++.

The problem is that, with the C API I'm working, the callback
function's signature doesn't specify which function is being called.
So if I register more than one callback with the same master callback
function I have no way of knowing how to dispatch the call. So I'm
stuck basically.

The above code is a simplified version of the actual C interface I'm
working with. If you're interested, the actual API is jsapi (Mozilla's
implementation of Javascript) and what I'm trying to do is use the
JS_DefineFunction call to bridge between Javascript and C++ by
allowing Javascript code to call C++ functions/functors.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
7/18/2007 7:00:55 AM
comp.lang.c++.moderated 10708 articles. 0 followers. allnor (8507) is leader. Post Follow

2 Replies
337 Views

Similar Articles

[PageSpeed] 48
assaf <assaflavie@gmail.com> wrote in news:1184758436.991084.129780
@z24g2000prh.googlegroups.com:

> I'm using a C API (it's actually Spidermonkey's jsapi) with which I
> can register callback functions:
> 
> void registerCallback(const char * name, CStyleFunctionPtr callback);
> 
> I'm trying to wrap and abstract away this API from my users by
> offering a pure C++ interface, in which users could implement callback
> via functions objects, or something similar. e.g.:
> 
> struct FooCallback : public CallbackFunction
> {
>      virtual void run() { /* ... /* }
> }
> 
> void registerCppCallback(CallbackFunction * pCB);
> 
> You get the point. This way my callbacks have state, I don't need to
> mess around with function pointers, my users don't have to even
> #include the C-API's headers and I can translate their arguments from
> the underlying API's C types to their equivalent STL classes.
> 
> My plan was to implement this by creating one "master" callback the C-
> way and have it act as a dispatcher to the actual callback
> implementations in C++.
> 
> The problem is that, with the C API I'm working, the callback
> function's signature doesn't specify which function is being called.
> So if I register more than one callback with the same master callback
> function I have no way of knowing how to dispatch the call. So I'm
> stuck basically.

I'm a little unclear what you mean here.  Wouldn't you be registering
by name?

> The above code is a simplified version of the actual C interface I'm
> working with. If you're interested, the actual API is jsapi (Mozilla's
> implementation of Javascript) and what I'm trying to do is use the
> JS_DefineFunction call to bridge between Javascript and C++ by
> allowing Javascript code to call C++ functions/functors.
> 
> 

Have a look at Boost/TR1 function:
http://www.boost.org/doc/html/function/tutorial.html#id1186501
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1402.html

Your storage could be something like std::map<std::string,
boost::function<...> > if your functions have the same signature.  The
function objects are typesafe and can store all sorts of functions,
including function pointers, functors, and binders.

The JSNative function pointer type was not immediately availabe in a
search, so you'll have to match that.

You could have something like this:
class CallbackMgr
{
    typedef CallbackT boost::function<int(int)>; //whatever JSNative is
    typedef ContainerT std::map<
        std::string,
        CallbackT>;
    ContainerT container;
public:
    // returns true if replacing old value
    bool register(const char * name, CallbackT callback)
    {
        return container.insert(std::make_pair(
            std::string(name),
            callback)).second;
    }
    int execute(const char * name, int arg)
    {
        ContainerT::const_iterator i = container.find(std::string(name));
        if (i != container.end) return i->second(arg);
        // do not-found error processing here...
    }
};

There's a minor drawback: std::string is kind of heavy as a key, so
you might want to look at yasli or Alexandrescu's article on maps with
expensive keys.  I doubt you really care.

You'll probably want to wrap all the various types for your own
sanity...

Generally if you have separable or fine-grained callback needs, then
Boost/TR1 function is the way to go.  If you have callbacks grouped
together logically and they all should be implemented, then it's
better to group them in a class having virtual functions:

// user must inherit and implement, see Non-Virtual Interface
class CallbackGroup
{
public:
    void f1() { f1Imp(); }
.....
    void fn() { fnImp(); }
    virtual ~CallbackGroup() = 0 { }
private:
    virtual void f1Imp() = 0;
.....
    virtual void fnImp() = 0;
};

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
W
7/18/2007 3:28:38 PM
assaf wrote:
> I'm using a C API (it's actually Spidermonkey's jsapi) with which I
> can register callback functions:
> 
> void registerCallback(const char * name, CStyleFunctionPtr callback);

Two questions here:
1. How does 'CStyleFunctionPtr' look like?
2. What is 'name' used for?

> I'm trying to wrap and abstract away this API from my users by
> offering a pure C++ interface, in which users could implement callback
> via functions objects, or something similar. e.g.:
> 
> struct FooCallback : public CallbackFunction
> {
> virtual void run() { /* ... /* }
> }
> 
> void registerCppCallback(CallbackFunction * pCB);
> 
> You get the point.

Ahem, not really: my first question would be who owns 'pCB' afterwards.

> This way my callbacks have state, I don't need to 
> mess around with function pointers,

...instead you mess around with object pointers with unclear ownership?
Seriously, consider either using references or use auto_ptr to make
ownership clear.

> my users don't have to even 
> #include the C-API's headers and I can translate their arguments from
> the underlying API's C types to their equivalent STL classes.
> 
> My plan was to implement this by creating one "master" callback the C-
> way and have it act as a dispatcher to the actual callback
> implementations in C++.
> 
> The problem is that, with the C API I'm working, the callback
> function's signature doesn't specify which function is being called.
> So if I register more than one callback with the same master callback
> function I have no way of knowing how to dispatch the call. So I'm
> stuck basically.

Okay. Typically, a C-style callback interface takes a function pointer and a
void pointers that holds some user-defined context. In you case, it could
only be the 'name', therefore also my initial two questions. If no such
thing is provided, there is nothing you can do. Otherwise, you could either
use the context to map to the object making the request or make the context
a pointer to the object itself.

Uli


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Ulrich
7/19/2007 8:55:15 AM
Reply:
Similar Artilces:

HDMI to VGA Adapter
Ref below:- http://www.amazon.co.uk/dp/B00Q2FSJWI?psc=1#customerReviews Does this converter make sense - is it possible to convert digital HDMI output to analogue VGA ? -- Colin Ferris Cornwall UK In article <155d75ac54.cferris@cferris.freeuk.com>, <cferris@freeRemoveuk.com.invalid> wrote: > Ref below:- > http://www.amazon.co.uk/dp/B00Q2FSJWI?psc=1#customerReviews > Does this converter make sense - is it possible to convert digital > HDMI output to analogue VGA ? Just about anything is possible. However, you'd need to check the one you wa...

Access USB device properties using C#
Hi, I asked a question about accessing USB devices previously and incorrectly stated my question. I'd like to know how I can obtain information about USB devices using C# such as the USB VID/PID. What is necessary for this? Sorry for the incorrectly worded question. Andy Andrew Falanga wrote: > I asked a question about accessing USB devices previously and > incorrectly stated my question. I'd like to know how I can obtain > information about USB devices using C# such as the USB VID/PID. What > is necessary for this? USB devices and their propertie...

c++ calling c functions
hi, i am trying 2 merge 2 projects into one project.One project is using c language and the other one is using c++ code. both are working very fine independently.But now i need to merge both and my c++ code should call c code.but when i tried to call a function in c code externing that function in my c++ code, i am getting unresolved external symbol error. Whatever i try its giving more and more errrors...so is it possible to merge 2 projects? if so how can i do that? please reply.... - Thejaswini On Dec 5, 9:20 am, teju <tejaswini_ra...@yahoo.co.in> wrote: > hi, > > i am ...

Which NTSC to VGA adapter is best for C64?
I'm looking to buy an NTSC to VGA adapter for my C64 since I just don't have the desk space for the old 1802D monitor anymore. I want one that does NOT require a PC but is just a standalone converter box, so any PCI or USB tuners are out. I've tried an "AverMedia TV Genie" once before and the picture quality through the S-video input looked quite good. Even the games with goofy color schemes were readable. Unfortunately this box has an annoying cooling fan which is almost as loud as a PC. So I'm looking for something equivalent, and so far I've found the K...

C++ linking problem, mismatched ABI
I am attempting to link a stand alone server C++. We recently moved to the 64 bit HP OS environment. Our other C++ Tuxedo services have effectively linked and successfully tested out fine under this OS, 3rd party library, and Oracle upgrade. However, I encounter this error message for this revamped C++/Source pro server I am re-writing. I can derive several guesses for what the potential problems are, but I would welcome a more accurate assessment of the issue. I could obviously use some pointers as to how best resolve this mismatch. if [ -f pif ]; then rm -f pif~; mv -f pif pif~; fi ...

SSA adapter testing
As part of a test if an AIX server has two SSA adapters attached, is it possible to detach one of the ssa adapters (changing its status from Available to Defined) to test resilence via one of the smitty menu's or command line. If one tries an rmdev -l ssa0 for example naturally it will not let you do this (if already connected to a LIVE SSA) complaining that the resource is busy. Any ideas ? Kam wrote: > As part of a test if an AIX server has two SSA adapters attached, is > it possible to detach one of the ssa adapters (changing its status > from Available to Defined) to test ...

COM mechanism
Hi all, I've just started to decipher the world of COM programming and I would appreciate if someone can clarify this: Why do I need to access a method in a class that implements an interface through a pointer to that interface? In other words, for instance, given the following: Interface InterfaceA { virtual void DoSomething()=0; }; class A : public InterfaceA { void DoSomething() } Why do I need to QueryInterface, to obtain a pointer to InterfaceA and through InterfaceA access DoSomething(). I hope I understood correctly the mechanism. Million thanks...

pg_ctl.c
--ELM1085457819-29798-1_ Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII I am almost finished Andrew's version of pg_ctl.c. Here is the current version I am using. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 --ELM1085457819-29798-1_ Content-Transfer-Encoding: 7bit Content-Type: text/plain Content-Disposition: inline; filename=&qu...

Reading a C struct in java
Hi, I am writing an app in java which reads data from a socket from a C language program. The data is encoded as a C struct of char arrays something like this; typedef struct { char type[1]; char length[6]; char acknowledge[1]; char duplicate[1]; ... } type_t; How can I decode a structure like this in Java without using JNI (a requirement)? -- (\__/) M. (='.'=) Due to the amount of spam posted via googlegroups and (")_(") their inaction to the problem. I am blocking most articles posted from there. If you wish your postings to be seen by everyone you...

adaptive huffman, ordinary data
oh well, I wrote something that is afaik similar to adaptive huffman (I just came up with my own algos here, using what I did for the static case as the base). it typically gives slightly worse compression than the static version, and takes a bit more time. this was not entirely unexpected however. maybe someone can look at the fragment at the bottom and tell me if this is even really "huffman", I feel unsure (similar goes for the static algo, as far as I can tell, the only strong similarities are that it is based on variable codes, uses a kind of tree, and I call it "hu...

array-style legend
Hi everyone, I would like to know if there is a way to display a plot's legend in the form of an array. I would like it to look somewhat like this http://i55.tinypic.com/32zs2eo.png I have seen methods saying to create several sets of axes but I have already several and I don't want my graphs to turn into a mess of axes. Is there maybe a way by creating an object and fill it with custom text and linestyle of the different curves ? Thanks very much for reading this, Romain ...

US-TX-Fort Worth: Java, C/C++, SABRE , NT/XP platform (45353157615)
US-TX-Fort Worth: Java, C/C++, SABRE , NT/XP platform (45353157615) =================================================================== Position: JAVA Developer Reference: MLS00014 Location: Fort Worth TX Duration: 4mo + Skills: 5+ YEARS Knowledge of SABRE Reservation system and IBM Kiosk platform a plus. Java, C/C++, on a windows NT/XP platform Scope: Provide senior level support utilizing Java, C/C++ on a Windows NT/Windows XP platform. strong knowledge of processes and procedu...

Open Source C/C++ Library for Arithmetic Expression Simplification
I was looking for a library that would allow me to do this: Give it an expression that all uses variables of the same type. (ints, floats, whatever) Allows me to turn that expression into a function. Subsequently allowing me to call that function. Basically this is equivalent to just compiling a simple function that consists of a single arithmetic function where the result of the function is the result of the expression. And then I would like a handle to call that function. All of this, I would like to be able to do at runtime. I have (only known at runtime): ...

How miniport driver indicate the adapter unbind ??
Hi friends, I have a wireless adapter. When I remove the adapter how the miniport driver will indicate the NDIS ?. Which NDIS function it is using to indicate that adapter is no longer present.? Is it actually calling any function or some other method ??. Please help me.. Thanks and regards, Biju CP ...

multiple adapters, same clid
Is there a provider that serves (310) that can provision the same outbound CLID on multiple adapters (each with its own inbound number)? We want to have seperate lines in the kids rooms (cable modem), the den (business dsl paid for by the office), garage and living room (Verizon dsl), but all outgoing calls will display the number in the living room. Thanks Dave ...

ps/2 to ps/1 adapter
Hi First of all, sorry for my not-so-good english I have this very awesome dvorak-keyboard, and it types very well, but the problem I have is that the dvorak is rather old and has a ps/1 plug. the computer I work on only has a ps/2 So I went to the store, to buy a ps/1 to ps/2 adapter, and almost every store in the neigbourhood says they don't sell it anymore. My question is: does anyone know the scheme of such adapter, so I can make it myself? (plugs aren't the problem, but I'm wondering which pin should be connected to which pin) Thanks in advance Theo Vermeulen -- The...

Style question
I'm not after a definitive answer here - I know there aren't any. But I'm curious to know how people feel about something. A few days ago I found myself writing something like this: find_item(name)->identifier Where find_item looks up a name in a data structure and returns a pointer to the node (a struct). The "identifier" is an integer. I was, in fact, using this as a paramater to another function, that took an integer identifier and did some more stuff with it. There's a bit of me that thinks this is really neat, and another bit of me that fo...

Using C# COM object in VO
Hi, I just wrote a small assembly in C#, that I want to use with Visual Objects. I registered the assembly and used the VO wizard to add a stub for my COM object. Unfortuantely whenever I want to call a method (SayHelloForeigner) of my assembly VO comes with an error "OLE AutoObject has not been initialized or is already destroyed". Does somebody knows why? My C# code: public interface IHello { string SayHelloForeigner(); string SayHello(string sName); } [ClassInterface(ClassInterfaceType.None)] public class HelloImpl:IHello { ...

802.11b USB network adapter drivers
how would the process to make solaris 10 work with this SMC 802.11b USB wireless network adapter compare with the linux process: <http://www.smc.com/index.cfm?event=viewProduct&localeCode=EN_CAN&cid=5&scid=&pid=486> the linux driver is, hopefully, at: <http://atmelwlandriver.sourceforge.net/downloads.html> the linux driver suggests recompiling, or at least getting the kernel sources ..config file. the source code for solaris 10 isn't available, that'd be Open Solaris. So, just curious how solaris folks manage with driver issues such as this one. than...

US-TX-Austin: Product Characterization Eng. RF test/product exp., VB, C or C#; P (45339857608)
US-TX-Austin: Product Characterization Eng. RF test/product exp., VB, C or C#; P (45339857608) ============================================================================================== Position: Product Characterization Eng. Reference: SMC01920 Location: Austin TX Duration: Perm Skills: Qualifications � MSEE or BSEE � 0-5 years in RF test/product experience. � Strong software development background. � Strong written / verbal communication & presentation skills. � St...

The diifferences between adaptable and adaptive systems?
Are differences between adaptable and adaptive human-computer systems? Victor Andreev I would imagine so, even by the definition of adaptive & adaptable. The difference i perceive is, the way a human-computer systems adapts itself, An Adaptable systems is where the "human" can "adapt" the system to their desired method of use. Whereas an Adaptive systems is a systems which adapts itself from how the users interact with it. An example of this is the Windows/office "intelligent" menu system. I hope i am making sense here, as i don't ...

Adapter Connector -- Laptop HDD to Standard PC Ribbon Cable
Hi. We have an HP laptop computer that has an IDE HDD that we want to recover data from. We must do this by booting to a regular cabinet model computer that will be directly connected to the laptop's HDD via one of the regular computer's IDE channels. Of course we will boot to the OS of the regular computer, not the OS of the laptop HDD. Is there an adapter connector that will connect a vintage 1998 IDE (DMA mode-2) ribbon cable of a regular cabinet model PC to the HDD of a 2002 Hewlett-Packard laptop model (HDD probably manufactured by Fujitsu)? If so, then who has them for sale? ...

US-AL-Huntsville: SAP BW Developer, SAP BW, ABAP, SAP R/3 (FI/CO); C-P (45299832403)
US-AL-Huntsville: SAP BW Developer, SAP BW, ABAP, SAP R/3 (FI/CO); C-P (45299832403) ==================================================================================== Position: SAP BW Developer Reference: SMC01387 Location: Huntsville AL Duration: C-P Skills: 9+ yrs application development with 5+ yrs SAP development and implementatioin SAP BW ABAP Large systems development SAP R/3 (FI/CO) module full systems development life cycle (analysis, design, progra...

US-TX-Austin: Product Characterization Eng. RF test/product exp., VB, C or C#; P (45338532415)
US-TX-Austin: Product Characterization Eng. RF test/product exp., VB, C or C#; P (45338532415) ============================================================================================== Position: Product Characterization Eng. Reference: SMC01920 Location: Austin TX Duration: Perm Skills: Qualifications � MSEE or BSEE � 0-5 years in RF test/product experience. � Strong software development background. � Strong written / verbal communication & presentation skills. � Strong troublesh...

running c code low latency
Hello, We are designing a project to acquire biomedical signals. For this project to suceed our program must run in real-time with approximately 5 msec of latency. In order to implement one of our algorithms we need to use C-code/MATLAB. We are using MATLAB to create a multidimensional array defined in size by the user based on previously acquired signals. When we tested how fast our C/MATLAB code ran (using the Timing Template VI that is included in the LabVIEW examples) we found that it ran between 9 and 10 msec. We were wondering if there were ways to use external code more efficiently. ...