error with callback function - callback

I am trying to register a keyboard callback function to a 3D viewer using the Point Cloud Library API.
Todo this I do:
viewer->registerKeyboardCallback(&(RailExtraction::keyboard_callback), (void*)(&gt_data));
But I get the following error message:
note: no known conversion for argument 1 from 'void (RailExtraction< pcl::PointXYZI >::*)
(const pcl::visualization::KeyboardEvent&, void*)' to 'void (*)(const pcl::visualization::KeyboardEvent&, void*)'
I am trying to understand the error message. I understand what void and void * mean but what does void(*)(...) or void(RailExtraction< pcl::PointXYZI >::*>(...) mean ??

I figured out the problem I am using the wrong version of registerKeyBoardCallBack. I am currently trying to use this signature:
registerKeyboardCallback (void (*callback) (const pcl::visualization::KeyboardEvent&, void*), void* cookie = NULL)
But I should be using this signature:
registerKeyboardCallback (void (T::*callback) (const pcl::visualization::KeyboardEvent&, void*), T& instance, void* cookie = NULL)
This is because my keyboard_callback function is part of a class and therefore I need to specify the instance of the class so that the compiler can figure out which instance the keyboard_callback function to use. Therefore my new call to registerKeyboardCallBack looks like this:
viewer->registerKeyboardCallback(&RailExtraction::keyboard_callback, *this, (void*)&gt_data);

Related

Callbacks in Dart: dart:ffi only supports calling static Dart functions from native code

This post is a duplicate of the Github Issue here.
dart --version
Dart SDK version: 2.15.0-116.0.dev (dev) (Thu Sep 16 09:47:01 2021 -0700) on "linux_x64"
I've been looking up examples for callbacks and I have tried to get callbacks working for me in FFI.
My current situation
I have a function in my library which expects a pointer to a function. The bindings for the same generated by ffigen seem correct to me.
int SetCallback(
CallbackType callback,
) {
return _SetCallback(
callback,
);
}
late final _SetCallbackPtr =
_lookup<NativeFunction<Int32 Function(CallbackType)>>(
'SetCallback');
late final _SetCallback =
_SetCallbackPtr.asFunction<int Function(CallbackType)>();
where, typedef CallbackType = Pointer<NativeFunction<Void Function(Uint32)>>;.
What I want to do here is to setup this callback in Dart, pass it to the FFI, essentially using it as my callback as I would have in C. In my API which abstracts away from FFI code (which means I have a class MyLibrary full of static functions that the user will call directly, which in turn calls functions from an object _nativeLibrary of the class MyNativeLibrary I have created), I have:
static int SetCallback({required CallbackFuncDart callback}) {
Pointer<NativeFunction<CallbackFunc>> pointer = Pointer.fromFunction(callback);
int status = _nativeLibrary.SetCallback(
pointer,
);
if (STATUS_OK != status) {
throw LibLexemeException(status);
}
return status;
}
typedef CallbackFunc = Void Function(Uint32);
typedef CallbackFuncDart = void Function(int);
While the sqlite ffi example states here that
Features which dart:ffi does not support yet:
Callbacks from C back into Dart.
I believe the docs haven't been updated to reflect the changes at the samples here. The samples haven't been very clear due to them not having any C/C++ files, or an idea of how the C functions work. Even so, I think this example contains a segment(last code block) where a Dart function is being passed as a callback which I have replicated in my program. It is not clear to me how this will work but upon trying to compile my program I get:
ERROR: ../lib/library_lexeme.dart:180:74: Error: fromFunction expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code. Closures and tear-offs are not supported because they can capture context.
ERROR: Pointer<NativeFunction<CallbackFunc>> pointer = Pointer.fromFunction(callback);
The short version is that you can't pass your callnback as an argument:
static int SetCallback({required CallbackFuncDart callback}) {
Pointer<NativeFunction<CallbackFunc>> pointer = Pointer.fromFunction(callback); // <-- this isn't considered a static function
It's quite annoying but you must use a static function defined ahead of time for your dart callbacks to be called from C.
Apparently for now only static functions can be passed via ffi. But if you have to access an instance's data and you're sure that the instance exists you can use my workaround. I use a static list to the instances. This is stupid and ugly but it works for me:
class CallbackClass {
static Int8 classCallback(int id) {
final instance = instanceList[id];
return instance.instanceCallback();
}
Int8 instanceCallback() { return instanceId; }
static List<CallbackClass> instanceList = <CallbackClass>[];
late final int instanceId;
CallbackClass {
instanceId = instanceList.length;
instanceList.insert(instanceId, this);
myFFImapping.passCallback(instanceId, Pointer.fromFunction<>(classCallback);)
}
}
I omitted the necessary c code, FFI mapping and casting to correct types for clarity, so it obviously won't compile like this.

Dart/Flutter ffi (Foreign Function Interface) native callbacks eg: sqlite3_exec

Hello I am using dart:ffi to build an interface with my native c/c++ library.
and I needed a way to get a callback from c to dart as an example in sqlite:
int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
the third parameter in sqlite3_exec is function pointer to a callback.
so if I called this function in dart using ffi I need to pass a function pointer: and in dart:ffi Pointer class there is a function named fromFunction witch accepts a dart static function and an exceptionalReturn; but just by calling this function to get the function pointer of a dart managed function: a (sigterm) is raised and the dart code no long work in the process.
So My Question: Is there any way to get a native callback in dart, as in Python, c#, ..
Extra:
Is there any way to include dartino in a flutter project, since this ForeignDartFunction covers what I need.
I got an example to work. Hopefully you can adapt this to your case.
Example C function
EXTERNC int32_t foo(
int32_t bar,
int32_t (*callback)(void*, int32_t)
) {
return callback(nullptr, bar);
}
Dart code
First the typedefs. We need two for the native function foo and one for the Dart callback.
typedef example_foo = Int32 Function(
Int32 bar, Pointer<NativeFunction<example_callback>>);
typedef ExampleFoo = int Function(
int bar, Pointer<NativeFunction<example_callback>>);
typedef example_callback = Int32 Function(Pointer<Void>, Int32);
and the code for the callback
static int callback(Pointer<Void> ptr, int i) {
print('in callback i=$i');
return i + 1;
}
and the lookup
ExampleFoo nativeFoo =
nativeLib.lookup<NativeFunction<example_foo>>('foo').asFunction();
and, finally, use it like this:
int foo(int i) {
return nativeFoo(
i,
Pointer.fromFunction<example_callback>(callback, except),
);
}
as expected, foo(123) prints flutter: in callback i=123 and returns 124

From python how to pass frame object received in sys.settrace callback to c++ function which takes void *

from the call back function of sys.settrace how to pass frame object to a c++ which accepts void *
Limitations (in a given situation):
Forced to use sys.settrace (can not use PyEval_SetTrace)
Also c++ function can not accept PyObject* or PyFrameObject*
C++ code (using SWIG python bindings are generated for this):
class TEST_DECLS InterpPython{
static int TraceHook(void *frame, hwString what, void * arg);
}
Python code:
sys.settrace(_trace_hook)
def _trace_hook(frame, event, arg):
InterpPython_TraceHook(frame,event, arg)
Results:
TypeError: in method 'InterpPython_TraceHook', argument 1 of type 'void *'
Try a typemap to convert the Python input object to a void* when it is a void* frame parameter. You could also add a check that the object is actually a PyFrameObject.
%typemap(in) void* frame %{
$1 = (void*)$input;
%}

va_arg prevents me from calling a managed delegate in a native callback

In a C++/CLI assembly, I'm trying to call a managed delegate from a native callback. I followed Doc Brown's answer here, and my implementation so far looks like this:
The native callback - ignore the commented out parts for now:
static ssize_t idaapi idb_callback(void* user_data, int notification_code, va_list va)
{
switch (notification_code)
{
case idb_event::byte_patched:
{
//ea_t address = va_arg(va, ea_t);
//uint32 old_value = va_arg(va, uint32);
return IdaEvents::BytePatched(0, 0);
}
break;
}
return 0;
}
As you can see above, I call this managed delegate instantiated in a static class:
public delegate int DatabaseBytePatchedHandler(int address, int originalValue);
private ref class IdaEvents
{
static IdaEvents()
{
BytePatched = gcnew DatabaseBytePatchedHandler(&OnDatabaseBytePatched);
}
public: static DatabaseBytePatchedHandler^ BytePatched;
private: static int OnDatabaseBytePatched(int address, int originalValue)
{
return 0;
}
};
This compiles fine. But the code is incomplete - remember the commented out part in the native callback above? I actually have to retrieve the values from the va_list passed to the callback, and pass those on to my managed delegate:
ea_t address = va_arg(va, ea_t);
uint32 old_value = va_arg(va, uint32);
return IdaEvents::BytePatched(address, old_value);
But as soon as I uncomment one of the lines using va_arg, I cannot compile the project anymore and retrieve the following errors marking the line where I call the managed delegate:
C3821 'IdaEvents': managed type or function cannot be used in an unmanaged function
C3821 'IdaEvents::BytePatched': managed type or function cannot be used in an unmanaged function
C3821 'BytePatched': managed type or function cannot be used in an unmanaged function
C3821 'DatabaseBytePatchedHandler::Invoke': managed type or function cannot be used in an unmanaged function
C3642 'int DatabaseBytePatchedHandler::Invoke(int,int)': cannot call a function with __clrcall calling convention from native code
C3175 'DatabaseBytePatchedHandler::Invoke': cannot call a method of a managed type from unmanaged function 'idb_callback'
This really confuses me. Why is the compiler suddenly acting up as soon as I try to use va_arg? Even a single line without any assignment causes this error to pop up.
Am I thinking too naive here? I'm obviously missing a piece of the puzzle, and any help supporting me in finding it is greatly appreciated.

PowerRegisterSuspendResumeNotification - provided callback function doesn't work as expected

I register my application to receive notification when the system is suspended or resumed.
MSDN documentation
Function I'd like to be executed after application receives notification (I tried both void and void CALLBACK and both work same way):
void isConnectedStandby()
{
printf( "ConnectedStandby Request");
}
1st case - I provide pointer to the isConnectedStandby function, but system treats as a double pointer to the function - it calls an address which is under this callback pointer.
HPOWERNOTIFY RegistrationHandle;
PowerRegisterSuspendResumeNotification(
DEVICE_NOTIFY_CALLBACK,
&isConnectedStandby,
&RegistrationHandle
);
2nd case - here I provide as follows (this way my function code is executed):
typedef void (*StatusFunction_t)();
StatusFunction_t StatusFunction = isConnectedStandby;
HPOWERNOTIFY RegistrationHandle;
PowerRegisterSuspendResumeNotification(
DEVICE_NOTIFY_CALLBACK,
&isConnectedStandby,
&RegistrationHandle
);
System calls not only mine function, but all addresses after the first one (if I provide an array of functions, it executes one after another to crash when there is no valid code available)
What is the correct way to use this function?
Function declaration (must be static ULONG with 3 parameters as you can see below):
static ULONG isConnectedStandby(PVOID Context, ULONG Type, PVOID Setting);
ULONG isConnectedStandby(PVOID Context, ULONG Type, PVOID Setting)
{
printf( "ConnectedStandby Request");
return 0;
}
Istead of providing callback function directly to PowerRegisterSuspendResumeNotification we have to provide struct _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS filled with our functions address :
static _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS testCallback = {
isConnectedStandby,
nullptr
};
HPOWERNOTIFY RegistrationHandle;
PowerRegisterSuspendResumeNotification(
DEVICE_NOTIFY_CALLBACK,
&testCallback,
&RegistrationHandle
);
MSDN documentation did not mention any of those information.