Using a Function pointer inside a class crashes the compiler (but works inside a function) - class

Reference class
class commandsListClass
{
public:
std::string name;
std::string description;
std::vector<std::string> commands;
columnHeaders headersRequired;
void (*function)(System::Object ^ );
std::string recoveryFileHeader;
void reset()
{
name = "";
description = "";
commands.clear();
headersRequired.reset();
recoveryFileHeader = "";
function = dummyFunc; // dummyFunc uses the same members as the intended - this is to ensure it is defined. DummyFunc is empty, returns void etc
}
commandsListClass()
{
reset();
}
};
Currently, if I run the below code, the compiler crashes
// This crashes the compiler
System::Threading::ThreadPool::QueueUserWorkItem(gcnew System::Threading::WaitCallback(global::commandsList[index].function ), ti);
1>------ Build started: Project: MyProject, Configuration: Release x64 ------
1> project.cpp
1>c:\users\guy\documents\visual studio 2012\projects\MyProject\MyProject\Form1.h(807): fatal error C1001: An internal error has occurred in the compiler.
1> (compiler file 'msc1.cpp', line 1443)
1> To work around this problem, try simplifying or changing the program near the locations listed above.
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
If I declare a member inside the same function as I am making the call, and set it to the global::commandsList[index].function, it compiles and runs correctly
// This runs correctly
void (*func)(System::Object ^);
func = global::commandsList[index].function;
System::Threading::ThreadPool::QueueUserWorkItem(gcnew System::Threading::WaitCallback(func ), ti);
global::commandsList is a vector of type commandsListClass
Any ideas? Browsing Google and SO suggest changing the compiler to not optimize, which I've tried with no success. The code is written in such a way that:
That point in the code cannot be reached if index does not point to a valid member of the global::commandsList vector
The function variable is guaranteed to be set, either to the dummyFunc on creation, or the correct (requested) function as set elsewhere in the code.
Any help would be greatly appreciated.
Edit 1: This is using Visual Studio 2012, Windows 7 x64

Here's a simplified repo:
public delegate void MyDel(Object^);
void g(Object^) {}
struct A {
static void(*fs)(Object^);
void(*f)(Object^);
gcroot<MyDel^> del;
};
void(*fg)(Object^);
void h()
{
void (*f)(Object^);
A a;
gcnew MyDel(f);
gcnew MyDel(fg);
gcnew MyDel(a.fs);
a.del = gcnew MyDel(g);
//gcnew MyDel(a.f); // this line fails
// work around
f = a.f;
gcnew MyDel(f);
}
Only the non-static member variable fails. Seems like a compiler bug. Work around it by using a local intermediate.
Or better is Lucas's suggestion to use gcroot.

Related

undefined reference error in VScode Version 1.69.1

Below is simple program where i have configured VSCode on Azure VM with all applicable extensions to run c program
But when i try to compile i am getting below error
Any hints or missing extensions will assist... if i define func() at top prior main() it works but would be interested to know how do i make it work the way i am trying too ..any hints will be appreciated..
Place your entire void meow(void) function definition:
void meow(void) {
printf("meow\n");
}
outside of the main() function definition brackets { } like so:
int main(void) {
...
...
}
void meow(void) {
printf("meow\n");
}

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.

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.

Is it true that for all .NET operator overload methods must be public and static?

Quoted from C# From CLR
The CLR specification mandates that operator overload methods be
public and static methods.
I checked ECMA-335, but couldn't find any evidence.
So far I know it is true for C# and F#. Is it true for all CLS-compliant language?
It looks like it's not really required to be public, but making it non-static is problematic at execution time. I experimented by starting with this code:
using System;
class Oddity
{
public static Oddity operator+(Oddity x, Oddity y)
{
Console.WriteLine("Adding oddities");
return null;
}
}
class Test
{
static void Main()
{
var x = new Oddity();
var y = new Oddity();
var z = x + y;
}
}
... and then running it through ildasm, changing things, then using ilasm and running the result.
Changing the accessibility modifier to assembly (equivalent to internal): all was fine
Changing the accessibility modifier to private: it assembled (which surprised me) but then failed at execution time:
Unhandled Exception: System.MethodAccessException: Attempt by method 'Test.Main()' to access method 'Oddity.op_Addition(Oddity, Oddity)' failed.
at Test.Main()
Removing the static part: it assembled (again, surprising me) but then failed at execution time:
Unhandled Exception: System.MissingMethodException: Method not found: 'Oddity Oddity.op_Addition(Oddity, Oddity)'.
at Test.Main()
I suspect these really should be caught at assembly time, but as languages are only expected to produce operators which are public and static, the validator is a little lax.

Call function in main program from a library in Arduino

I've just started making libraries in Arduino. I've made a library named inSerialCmd. I want to call a function named delegate() that is defined in the main program file, stackedcontrol.ino, after the inSerialCmd library is included.
When I try to compile, one error is thrown:
...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp: In member function
'void inSerialCmd::serialListen()':
...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp:32: error:
'delegate' has not been declared
After doing a bit of searching, it seemed that adding the scope resolution operator might do the trick. So I added the "::" before delegate(), now "::delegate()", but the same error is thrown.
Now I'm stumped.
You cannot and should not directly call a function in a program from a library. Keep in mind a key aspect that makes a library into a library:
A library does not depend on the specific application. A library can be fully compiled and packaged into the .a file without the existence of a program.
So there is a one way dependency, a program depends on a library. This at first glance may seem to prevent you from achieving what you want. You can achieve the functionality you are asking about through what is sometimes referred to as a callback. The main program would provide to the library at runtime a pointer to the function to execute.
// in program somwehere
int myDelegate(int a, int b);
// you set this to the library
setDelegate( myDelegate );
You see this in the arduino if you look at how interrupt handlers are installed. This same concept exists in many environments - event listeners, action adapters - all with the same goal of allowing a program to define the specific action that a library cannot know.
The library would store and call the function via the function pointer. Here is a rough sketch of what this looks like:
// in the main program
int someAction(int t1, int t2) {
return 1;
}
/* in library
this is the delegate function pointer
a function that takes two int's and returns an int */
int (*fpAction)(int, int) = 0;
/* in library
this is how an application registers its action */
void setDelegate( int (*fp)(int,int) ) {
fpAction = fp;
}
/* in libary
this is how the library can safely execute the action */
int doAction(int t1, int t2) {
int r;
if( 0 != fpAction ) {
r = (*fpAction)(t1,t2);
}
else {
// some error or default action here
r = 0;
}
return r;
}
/* in program
The main program installs its delegate, likely in setup() */
void setup () {
...
setDelegate(someAction);
...