I need to find a way to retrieve callbacks from C++/Cx back to native C++. In C++ code those are stored as function pointers, while in C++/Cx they are stored in delegates. I've found that in C# and C++/CLI there is a function like GetFunctionPointerForDelegate() but seems like there is nothing even similar to this one in C++/CX. Is there really any solution to this problem ?
The C++/Cx is the medium layer between C# app and C++ native library. And i managed to pass a pointer from C# to WinRt(C++/Cx) layer as follows:
del d = new del(callBackFunction); //declare a delegate and
//add a function to delegate
IntPtr p = GetFunctionPointerForDelegate(d); //retrieve pointer
w.retrieveCallbackFunction(p.toInt32()); //pass a pointer as int to WinRt layer
Inside WinRt layer inside retrieveCallbackFunction:
void* x=(void*)p; //cast it to void*
callbackFunctionType ptr = (callbackFunctionType)x; // cast it to a type
// of function pointer
ptr(...); //call function
I know this isn't the prettiest solution but this one worked for me now.
EDIT
It also might be a good idea to prevent garbage collector from collecting function or delegate
GCHandle callbackHandle = GCHandle.Alloc(d); // !!!!
But now it is up to us to free this memory later.
I have no clue about C++/CX but a quick search brought this up which for me sounds like what you are trying to accomplish:
codeproject.com: Convert a Delegate to a Function pointer to Implement Callback function
Related
If I am given a pointer to an object and I need to pass one of that object's methods as an argument to another function, is that possible?
A very simplified example would look like this:
void consumeAFunction(Function func) {
auto value = func();
// do some stuff //
}
void main(Object *pointerToObject) {
consumeAFunction(pointerToObject->someMethod)
}
I've tried the following, but I think my understanding of pointers and references is flawed. I'm 3 weeks old in my c++ journey.
Object someObject = pointerToObject and Object someObject = *pointerToObject
The specific context of the question is that I have a pointer to an object created by some other library and I need to use QtConcurrent::run on that object's methods.
Additional context
consumeAFunction is QtConcurrent::run
Function func is a method of an Engine that simply performs some logic. I am handed a pointer to Engine by a third party library.
I cannot avoid using a pointer to Engine, because it is all I am given to work with.
As much of the specific code as I am allowed to show:
// engine is the pointer to someObject:
auto engine = lui::QueryInterop<wise::Engine>(lui::GetLUI());
if (engine) {
connect(&m_modelsLoadedWatcher, &QFutureWatcher<bool>::finished, this, &ConfigDialog::onNNModelsLoaded);
// This is the call to consumeAFunction (qtconcurrent::run)
m_modelsLoadedFuture = QtConcurrent::run(engine->loadPytorchModels);
m_modelsLoadedWatcher.setFuture(m_modelsLoadedFuture);
Because this is a Qt question, I highly recommend you get an understanding of QObject and QMetaObject::invokeMethod().
Because QObject is pre-processing via the moc-compiler, a lot of public interfaces, such as properties, methods are exposed in such a way that the object's properties and methods can be inspected at runtime by another plugin and that it doesn't need to know or have access to the header files. This is why something like QMetaObject::invokeMethod() can work because it has access to the metadata.
Alternatively, if you are using Javascript a lot in QML, you may be interested in passing a Javascript callback function to C++. That function is accessible via QJSValue. QJSValue usually is used to hold simple types such as strings and numbers. When it holds more complex Javascript types such as arrays, objects, or functions you can use quite a few QJSValue methods to unlock their capabilities. In the case of Javascript functions you can verify if it is a Javascript function with QJSValue.isCallable() == true and can you can execute it with QJSValue.call(...).
I am having some trouble passing a C++/CLI object pointer to a native object.
The entire picture is the following:
I am new to C++ in general (doomed)
I am using a third party native C++ library to interface a blackmagic IO video card. In the API there is a very handy method to pass a pointer of the object that will handle the frame callback while they are captured by the card:
SetCallback(Pointer to an object that implement an interface).
In the above SetCallback(Pointer) I would like to pass the pointer to my C++/CLI object. When I do so
I get: cannot convert argument 4 from 'CLIInterop::Wrapper ^*' to 'IDeckLinkInputCallback *'
My final target is to handle the callback from C++ into C++/CLI and at this point pass the frame over to WPF (if I will ever get that far)
The line of code invoved are:
Call from CLIInterop::Wrapper object
d_Controller->GetDevice()->StartCapture(0, nullptr, true, this);
Method header in the native C++ project:
__declspec(dllexport) bool DeckLinkDevice::StartCapture(unsigned int videoModeIndex, IDeckLinkScreenPreviewCallback* screenPreviewCallback, bool applyDetectedInputMode, IDeckLinkInputCallback* callbackHandler);
Help!
It is clearly indicate that your this pointer is not a type IDeckLinkInputCallback
d_Controller->GetDevice()->StartCapture(0, nullptr, true, this);
^ this pointer is not a type IDeckLinkInputCallback
As you told that you have already implement interface IDeckLinkInputCallback in the class of this pointer. Double check whether you have done it. Instead of calling StartCapture from the member function of the class better call it from outside and provide full address of the object instead this pointer.
You cannot just pass a managed reference ("hat pointer" ^) when a native pointer is expected. The whole point of C++/CLI is the possibility to create "glue" code such as what you're missing.
Basically, you would have to create a native class that implements the native interface, which may contain the managed reference that you call back to. I'm not familiar with the BlackMagic video card's interface (I used to have to work with DVS video cards, but their software interfaces are probably hardly comparable), but the general logic for such a wrapper would be similar to this:
class MyDeckLinkInputCallback : IDeckLinkInputCallback
{
public:
MyDeckLinkInputCallback(CLIInterop::Wrapper^ wrapper)
{
_wrapper = wrapper;
// initialize to your heart's content
}
private:
CLIInterop::Wrapper^ _wrapper;
public:
// TODO implement IDeckLinkInputCallback properly; this is just a crude example
void HandleFrame(void* frameData)
{
// TODO convert native arguments to managed equivalents
_wrapper->HandleFrame(...); // call managed method with converted arguments
}
};
I'm thinking about how to design my APIs, I plan to have a C++ application with a scripting layer in LUA .
For a couple of key points in my design I would like to give the ability to the user to create a function object that represents what he wants to do in LUA, than send this function object from LUA to C/C++ .
In pseudo code, in C++ I have a class T
class T {
...
int num1 = 0;
float num2 = 0.0f;
std::string str{"NONE"};
...
};
And I would like to manipulate an instance of T with a function object provided from LUA like so
void applyFunc(T t,F f){
f(t);
}
The problem is that I can't find nothing in LUA that creates a function object like a C++11 lambda or std::function or any other object that can be considered a function object.
Really my point is: how to define a C++ compatible function object in LUA ?
The problem is that I can't find nothing in LUA that creates a function object like a C++11 lambda or std::function or any other object that can be considered a function object.
That's what the function keyword does.
This is a lambda. It's easy enough to pass these to C++ and let the C++ code call them.
As for this:
void applyFunc(T t,F f){
f(t);
}
In principle it's easy: push the C++ object pointer onto the Lua stack as a userdata and call the Lua function. The problem is the Lua code can't do anything with a C++ pointer.
If you want the Lua code to be able to manipulate the object you pass it, you'll need to write manipulator methods in C++ and expose them to Lua. You usually do that by creating a metatable for the userdata.
There are libraries that this that automatically for C++. If you want to do it by hand (my preference), you should probably start here.
If you Google "C++ object Lua __index" that should net you numerous examples. I could code up an example later, but I'm at work at the moment.
I am new to Objective-C and I need to overcome the following issue.
I am trying to develop a front-end for a C library and I need to somehow get the address of an Objective-C member function and pass it to the library.
For instance: here's what I would do in C++
class MyClass
{
public:
void my function();
void some_other_function()
{ connect_signal(my_function); }
};
Here, I just pass the address of my_function() to connect_signal.
Is that possible in Objective-C? Any other ideas?
My second choice would be to simply write a C function out of the class that would call the Objective-C function.
Thanks in advance
There’s a methodForSelector: method that returns an IMP, a pointer to the implementation of a method for given selector (related question). Is that what you’re after?
And as a more general remark, using a pointer to a method implementation is usually too much magic. Is there a higher-level, more “ordinary” solution to your use case? (I can’t really imagine the details from what you wrote in the question.)
For the record, you can't connect a signal to a nonstatic C++ function. At least not in the *nix meaning of signals. Those need a this pointer for invokation.
Now, about Objective C. Depends on what do you want to do - pass a pointer to an Objective C method to a plain-C API, or implement a signal-like callback mechanism of your own. Other answers concentrate on the former; let's talk the latter.
The natural thing to do is passing around a combination of a selector and an object pointer. Selectors have datatype SEL and are retrieved using the #selector() construct. A selector is a piece of data (really an integer) that uniquely identifies a method within a class hierarchy.
Let's imagine you have a connect_signal function somewhere that wants a callback:
-(void)connect_signal:(SEL)callbackSelector forObject:(NSObject*)callbackObject;
You call it like this (from within the callback object):
[xx connect_signal:#selector(MyMethod:) forObject:self];
Within the function, you save the selector and the object pointer. When you need to invoke the callback, you would issue the following call:
[SavedCallbackObject performSelector:(SavedCallbackSelector) withObject: nil];
The second parameter is for passing parameters to the callback; if you need more than one, see NSInvoke.
My answer is assuming Cocoa. NSObject, e. g. is a Cocoa class. It's a safe bet for ObjC questions these days, considering.
Or you can use good old function pointers. They're still around.
An Objective-C method implementation (IMP) is a C function that takes at least two arguments; the target of the method call (self) and the selector to be invoked (_cmd).
Thus, passing an IMP to your C API won't work.
Your best bet is to pass a C function. Assuming your C API is sensible and has an "arbitrary user context pointer thingy", something like:
void myfunc(void *context) {
[(MyClass *)context callback];
}
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.