0

With C# 9 I can cast an address I get from a shared library to a function pointer and invoke it directly. This proved to be significantly more performant than mono's icalls or p/invoke and also less restrictive than the latter.

Now I have more than one function I wanna invoke but they have vastly different signatures. Is there a way to strap these signatures into a generic function? Something like this?

T GetPointer<T>(IntPtr module, string name) where T: delegate*<...> {
    var del = dlsym(module, name);
    if (del == IntPtr.Zero)
        Console.WriteLine(dlerror());
    return (T)del;
}

Of cause, omitting the generic constraint gives us an error about casting IntPtr to T.

What I could do, is pass the argument and return types as template arguments but that has the issue that I need to write this for every argument count twice since void isn't a valid template type.

delegate*<T, U, R> GetPointerWithReturn2<T, U, R>(IntPtr module, string name) { }
delegate*<T, R> GetPointerWithReturn1<T, R>(IntPtr module, string name) { }
delegate*<R> GetPointerWithReturn0<R>(IntPtr module, string name) { }
delegate*<T, U, void> GetPointer2<T, U>(IntPtr module, string name) { }
delegate*<T, void> GetPointer1<T>(IntPtr module, string name) { }
delegate*<void> GetPointer0(IntPtr module, string name) { }
lsbehe
  • 1
  • When you're going to produce lots of similar or identical functions you should be thinking of metaprogramming - T4 Templates or the new newness of Source Generators. Writing the code that writes the code tends to be a lot less "samey" and then when you discover you need to cover 5 arguments when previously you supported only up to 4 it's a loop end index change, not repetitive copy & paste. – Damien_The_Unbeliever Sep 09 '22 at 12:50

0 Answers0