i'm using fmodex and i'm trying to use FMOD_FILE_OPEN_CALLBACK under C++.
FMOD_RESULT F_CALLBACK FMOD_FILE_OPEN_CALLBACK(const char *name, unsigned int *filesize, void **handle, void *userdata);
But I would like to execute a method of a class. So I thought to pass current object this as userdata of the callback and execute my callback method as it's proposed here.
But unlike Fmod Studio, there is no fileuserdata in FMOD_CREATESOUNDEXINFO, only userdata pointer.
And documentation says :
[w] Optional. Specify 0 to ignore. This is user data to be attached to
the sound during creation. Access via Sound::getUserData. Note: This
is not passed to FMOD_FILE_OPENCALLBACK, that is a different userdata
that is file specific.
But how can I access this file specific pointer ? Or there is an other solution to do that ?
Thanks.
was this solved yet? If not here's how i do it.
FMOD_CREATESOUNDEXINFO* info = new FMOD_CREATESOUNDEXINFO();
info->cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
// This is the field you want to set
info->fileuserdata = someUserData;
_system->createStream(file.c_str(), FMOD_DEFAULT, info, &_currentSound);
Are you using an old version of the fmod library? On my system the fileuserdata field does exist. I'm using the fmodex low level api that shipped with the fmod studio installation.
When the API in question does not provide a user data pointer for the callback, but does provide some kind of handle, as seems to be the case here, then you can forward each callback call to a C++ method (a non-static member function) in two general ways + 1 API-specific way:
use API functionality to associate a C++ object pointer with each handle, or
use a static storage std::map or std::unordered_map that associates each handle with a C++ object pointer, or
use a dynamically created trampoline function with the object address hardwired.
The third option was used e.g. in Borland's ObjectWindows framework in the 1990's, and it's generally the fastest, but it conflicts with current malware protection schemes, and since the C++ standard library doesn't support it (and as far as I know Boost doesn't support it either, although The Good Puppy over in the C++ Lounge here at SO once made a proposal about it), it's necessarily platform specific machine code.
Thus, if you don't know a way to do the first option I suggest you go with the second, a std::map or std::unordered_map that associates handles with C++ objects.
The main remaining technical hurdle is then to decide the proper time to create a map entry, and the proper time to remove it. That is highly dependent on the callback scheme. And unfortunately I have zero experience with yours, but maybe others can chime in about that detail.
Related
I'm working at a module that use a callback system that wasn't implemented very nice. The clients are registering with an ID and will be called back with a variable (or two, or none). The problem is that for almost every ID is a different variable. (Ex: Id1 -> char*, Id2 -> int). This is achieved by passing variable via a pointer. So callback looks like
typedef void (*NotifFunctionPtr)(void* ctx, const void* option);
There are many problems with this approach like, and I want to replace this with a (type) safe and modern way of handling this. However this isn't as simple as it looks like, I have some ideas (like boost::function or replacing the void* with a struct that encapsulate type and ptr) but i think maybe there is a better idea, so I was wondering what is the modern way of settings a typesafe callback in C++.
Edit: Another idea is registering an callback with a type T via a template function that calls back with the same type T. Is this viable or implemented in a library somewere ?
Your problem is not that of callbacks, but rather that you want to treat all callbacks as the same type, when they are not (the signatures are different). So either you do the nasty C void* trick or if you want to use a type-safe approach you will have to pay for it, and provide different methods to register the different callback types --which IMHO is the right way.
Once you have solved that, you can use the signals or signals2 libraries or else implement your own wheel using function as a base (to avoid having to rewrite the type erasure).
boost::function is just the right choice here. You gain the type-safety of function objects without having to change the code much.
If you already looked into boost. Why not use the signals or signals2 library.
I'm in the process of writing a kind of runtime system/interpreter, and one of things that I need to be able to do is call c/c++ functions located in external libraries.
On linux I'm using the dlfcn.h functions to open a library, and call a function located within. The problem is that, when using dlsysm() the function pointer returned need to be cast to an appropriate type before being called so that the function arguments and return type are know, however if I’m calling some arbitrary function in a library then obviously I will not know this prototype at compile time.
So what I’m asking is, is there a way to call a dynamically loaded function and pass it arguments, and retrieve it’s return value without knowing it’s prototype?
So far I’ve come to the conclusion there is not easy way to do this, but some workarounds that I’ve found are:
Ensure all the functions I want to load have the same prototype, and provide some sort mechanism for these functions to retrieve parameters and return values. This is what I am doing currently.
Use inline asm to push the parameters onto the stack, and to read the return value. I really want to steer clear of doing this if possible!
If anyone has any ideas then it would be much appreciated.
Edit:
I have now found exactly what I was looking for:
http://sourceware.org/libffi/
"A Portable Foreign Function Interface Library"
(Although I’ll admit I could have been clearer in the original question!)
What you are asking for is if C/C++ supports reflection for functions (i.e. getting information about their type at runtime). Sadly the answer is no.
You will have to make the functions conform to a standard contract (as you said you were doing), or start implementing mechanics for trying to call functions at runtime without knowing their arguments.
Since having no knowledge of a function makes it impossible to call it, I assume your interpreter/"runtime system" at least has some user input or similar it can use to deduce that it's trying to call a function that will look like something taking those arguments and returning something not entirely unexpected. That lookup is hard to implement in itself, even with reflection and a decent runtime type system to work with. Mix in calling conventions, linkage styles, and platforms, and things get nasty real soon.
Stick to your plan, enforce a well-defined contract for the functions you load dynamically, and hopefully make due with that.
Can you add a dispatch function to the external libraries, e.g. one that takes a function name and N (optional) parameters of some sort of variant type and returns a variant? That way the dispatch function prototype is known. The dispatch function then does a lookup (or a switch) on the function name and calls the corresponding function.
Obviously it becomes a maintenance problem if there are a lot of functions.
I believe the ruby FFI library achieves what you are asking. It can call functions
in external dynamically linked libraries without specifically linking them in.
http://wiki.github.com/ffi/ffi/
You probably can't use it directly in your scripting language but perhapps the ideas are portable.
--
Brad Phelan
http://xtargets.heroku.com
I'm in the process of writing a kind of runtime system/interpreter, and one of things that I need to be able to do is call c/c++ functions located in external libraries.
You can probably check for examples how Tcl and Python do that. If you are familiar with Perl, you can also check the Perl XS.
General approach is to require extra gateway library sitting between your interpreter and the target C library. From my experience with Perl XS main reasons are the memory management/garbage collection and the C data types which are hard/impossible to map directly on to the interpreter's language.
So what I’m asking is, is there a way to call a dynamically loaded function and pass it arguments, and retrieve it’s return value without knowing it’s prototype?
No known to me.
Ensure all the functions I want to load have the same prototype, and provide some sort mechanism for these functions to retrieve parameters and return values. This is what I am doing currently.
This is what in my project other team is doing too. They have standardized API for external plug-ins on something like that:
typedef std::list< std::string > string_list_t;
string_list_t func1(string_list_t stdin, string_list_t &stderr);
Common tasks for the plug-ins is to perform transformation or mapping or expansion of the input, often using RDBMS.
Previous versions of the interface grew over time unmaintainable causing problems to both customers, products developers and 3rd party plug-in developers. Frivolous use of the std::string is allowed by the fact that the plug-ins are called relatively seldom (and still the overhead is peanuts compared to the SQL used all over the place). The argument stdin is populated with input depending on the plug-in type. Plug-in call considered failed if inside output parameter stderr any string starts with 'E:' ('W:' is for warnings, rest is silently ignored thus can be used for plug-in development/debugging).
The dlsym is used only once on function with predefined name to fetch from the shared library array with the function table (function public name, type, pointer, etc).
My solution is that you can define a generic proxy function which will convert the dynamic function to a uniform prototype, something like this:
#include <string>
#include <functional>
using result = std::function<std::string(std::string)>;
template <class F>
result proxy(F func) {
// some type-traits technologies based on func type
}
In user-defined file, you must add define to do the convert:
double foo(double a) { /*...*/ }
auto local_foo = proxy(foo);
In your runtime system/interpreter, you can use dlsym to define a foo-function. It is the user-defined function foo's responsibility to do calculation.
I am mixing Objective-C parts into a C++ project (please don't argue about that, its cross-platform).
I now want to invoke some C++ functions or methods on the correct thread (i.e. the main thread) in a cocoa enviroment.
My current approach is passing function pointers to an objective-c instance (derived from NSObject) and do performSelector/performSelectorOnMainThread on it.
But the performSelectors expect objects as their arguments, so how would one usually wrap this?
Example:
typedef void(*FnPtr)(void*);
FnPtr fn;
[someInstance performSelector:#selector(test:) withObject:fn];
... where test is declared as:
- (void)test:(FnPtr)fn;
Have to add that i only started with objective-c this week, so if there is a better way i'd be also glad to hear about it.
Also note that i don't have any access to the main loop or any application objects because the project is an browser plug-in (currently only targetting Safari on the mac).
As answered by smorgan here, NSValue is designed as a container for scalar C & Objective-C types:
- (void)test:(NSValue*)nv
{
FnPtr fn = [nv pointerValue];
// ...
}
// usage:
NSValue* nv = [NSValue valueWithPointer:fn];
[someInstance performSelector:#selector(test:) withObject:nv];
I am not sure if my solution is considered sane / correct -- I do however frequently pass pointers by simply typecasting them to (id)s. That is dirty but does work for me. The possibly cleaner way would be using NSValue.
or a VB6 - compatible - collection object.
We provide hooks into our .net products through a set of API's.
We need to continue to support customers that call our API's from VB6, so we need to continue supporting VB6 collection objects (simple with VBA.Collection in .net).
The problem is supporting some sites that use VBScript to call our API's. VBScript has no concept of a collection object, so to create a collection object to pass to our API we built a VB6 ActiveX DLL that provides a "CreateCollection" method. This method simply creates and passes back a new collection object. Problem solved.
After many years of pruning, porting and re-building, this DLL is the only VB6 code we have. Because of it we still need to install Visual Studio 6 on our Dev & build Machines.
I'm not happy with our reliance on this DLL for several reasons (my personal dislike of VB6 is not one of them). Top of the list is that Microsoft no longer support Visual Studio 6.
My question is, how do I get ATL to create a collection object that implements the same interface as the VB6 collection object.
I've a good handle on C++, but only a loose grasp of ATL - I can create simple objects and implement simple methods, but this is beyond me.
Collections are more or less based on convention. They implement IDispatch and expose some standard methods and properties:
Add() - optional
Remove() - optional
Item()
Count - read-only
_NewEnum - hidden, read-only, returns pointer to enumerator object that implements IEnumVariant
The _NewEnum property is what allows Visual Basic For Each.
In the IDL you use a dual interface and:
DISPID_VALUE for Item()
[propget, id(DISPID_NEWENUM), restricted] HRESULT _NewEnum([out, retval] IUnknown** pVal)
Here are some MSDN entries: Design Considerations for ActiveX Objects
And here is some ATL specific convenience: ATL Collections and Enumerators
Lets target this VBScript snippet
Dim vElem
For Each vElem In MyObject
...
Next
particularly the implementation of MyObject. As a minimum you have to implement a method/propget with DISPID_NEWENUM on the default dispinterface (its dual/dispinterface to talk about DISPIDs). You can name it whatever you want, it doesn't matter. Most collections use NewEnum, and flag it in IDL as hidden. VB6 uses underscore prefix to mark hidden methods so you might see _NewEnum as recommendation but it's kind of a cargo cult ATL does.
You don't need any Count, Item, Add, Remove, Clear or any other method at all (on the default interface). You can supply these as a convenience (particulatly Item accessor and probably Count) but you don't have to, to make the sample code above work.
Next, the retval has to be a separate object (so called enumerator) which implements IEnumVARIANT interface by using a (private) pointer to MyObject. In IDL you can declare retval as IUnknown nothing wrong here. What is most interesting is that you have to implement only the Next method on IEnumVARIANT, you can return E_NOTIMPLEMENTED on the rest if you like or optionally implement them though these are never called by For Each. What makes the implementation even easier is that celt parameter of Next (the number of items requested) is always 1, so For Each requests items always one by one.
What you can use in ATL is CComEnumOnSTL and the like to create a "proxy" enumerator on an STL container, or the array based enumerator ATL provides (and exclude STL).
For a good example of how to implement COM collections that would be used naturally in script programming languages, check out my website
It offers a comprehensive example of how to do that...
Continuing from this question, i am confused whether DISPID_VALUE on IDispatch::Invoke() for script functions and properties (JavaScript in my case) can be considered standard and reliable for invoking the actual function that is represented by the IDispatch?
If yes, is that mentioned anywhere in MSDN?
Please note that the question is about if that behaviour can be expected, not what some interfaces i can't know in advance might look like.
A simple use case would be:
// usage in JavaScript
myObject.attachEvent("TestEvent", function() { alert("rhubarb"); });
// handler in ActiveX, MyObject::attachEvent(), C++
incomingDispatch->Invoke(DISPID_VALUE, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, par, res, ex, err);
edit: tried to clarify the question.
It should be reliable for invokes on objects from scripts if the script defines it consistently. This should be the case for JScript/Javascript in MSHTML, but unfortunately there is really sparse documentation on the subject, I don't have any solid proof in-hand.
In my own experience, a Javascript function passed to attachEvent() should always be consistent- an object received that is a 'function' can only have one callable method that matches itself. Hence the default method is the only one you can find, with DISPID 0. Javascript functions don't ordinarily have member functions, although i'm sure there is a way for this to be possible. If it did have member functions, you would see them the same way as member functions on objects. Member functions in JScript will always be consistent with regard to IDispatchEx, according to the rules of expando functions, as any functions added to an object count as expandos.
IDispatchEx interface # MSDN
The default method or property that DISPID_VALUE invokes should be consistent for a given interface. That method/property has to be specified as DISPID_VALUE in the definition of the interface in the IDL for the type library. The only way it could change is if the owner of the interface released a new version of the interface that changed which method/property was the default but that would violate a fundamental rule of COM interfaces.
As meklarian said, DISPID_VALUE (0) seems to work pretty consistantly for JS functions (thus it works great with a custom attachEvent). I've been using them this way for about a year, and it's always worked. I've also found with an activeX control embedded with an <object> tag that to get it to work consistently, I need to implement IConnectionPointContainer and IConnectionPoint for the main (object tag) IDispatch-implementing CComObject, but any others that I expose to javascript as return values from methods or properties (through Invoke) I have to implement attachEvent and detachEvent myself.
When using Connection Points, the IDispatch objects in question will expect events to be fired to the same DISPID as they are attached to on your IDispatch object..
see http://code.google.com/p/firebreath/source/browse/src/ActiveXPlugin/JSAPI_IDispatchEx.h for an example of implementing the ConnectionPoints.
You can add DISPID's to a DISPINTERFACE, but you cannot change them once it has been published. If you need to, you can use IDispatch::GetIDsOfNames to map names to DISPIDs.
Pick up a copy of Inside Ole (2nd ed) and Inside Ole 2 (2nd ed) for a few bucks used on Amazon. It's a good reference for these obscure OLE incantations.