F# - how can I convert an F# function into a System.Delegate using reflection? - asp.net-core

Say I have a basic function, like:
let double x = x * 2
Since I know the types, I can convert it into a Func<_,_> explicitly, which can then be used as a Delegate:
let doubleFuncExplicit = Func<int, int>(double)
However, when I attempt to do this by using Activator.CreateInstance() instead of the constructor, like so:
// derive the type for Func<int, int>
let genericType = typeof<Func<obj, obj>>.GetGenericTypeDefinition()
let specificTypeDef = genericType.MakeGenericType([| typeof<int>; typeof<int> |])
// ...and instantiate it
let doubleFuncReflected = Activator.CreateInstance(specificTypeDef, [| double |])
...I get the following exception on the last line:
System.MissingMethodException: Constructor on type 'System.Func`2[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' not found.
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
at System.Activator.CreateInstance(Type type, Object[] args)
at <StartupCode$FSI_0007>.$FSI_0007.main#() in C:\dev\2023\MoneyClock2023\src\MoneyClock\MoneyClock.Tests\Scratch.fsx:line 16
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
Am I on the right track? How can I convert an F# function into a delegate?

Your code does not work, because when you pass [| double |] as arguments to Activator.CreateInstance, the double function becomes an F# first-class function (a class inherited from generic Microsoft.FSharp.Core.FSharpFunc<_, _> that the runtime has no way of understanding.
I believe you probably need to use Delegate.CreateDelegate. This takes an object instance and a method you want the delegate to invoke.
The F# first-class function type has an Invoke method and so if you take double as a value, you can use that as the instance and pick its Invoke method. The following works for me:
open System
let double x = x * 2
let doubleFuncExplicit = Func<int, int>(double)
let genericType = typeof<Func<obj, obj>>.GetGenericTypeDefinition()
let specificTypeDef = genericType.MakeGenericType([| typeof<int>; typeof<int> |])
let f = double // To make sure we have the function as a value
let mi = f.GetType().GetMethod("Invoke")
let doubleFuncReflected = Delegate.CreateDelegate(specificTypeDef, f, mi)
// You can cast and invoke the returned delegate
(doubleFuncReflected :?> Func<int, int>).Invoke(123)

Related

How to get the value of a CPointer in Visual Works

The following C function populate a C struct in Visual Works (is working ok):
<C:int ssh_pki_import_pubkey_file (const char * filename, VOID * pkey)>
Now a second function is defined as:
int ssh_userauth_try_publickey (ssh_session session, const char * username, const ssh_key pubkey)
In Smalltalk:
<C:int ssh_userauth_try_publickey (VOID session, const char * username, const VOID pubkey)>
If i call the second function (ssh_userauth_try_publickey) with the populated argument (with no transformation) of the first function (ssh_pki_import_pubkey_file) it fail.
So VOID * pkey has to match const VOID pubkey.
In GemStone/S this is done with #'&ptr' and #'ptr', so #'&ptr' will get the value of the pointer (the CPointer’s value will be passed and updated on return).
Reading DLL & C Connect User’s Guide does not yield result yet.
Short answer
use void** in your first function and void* in your second function
Long answer
In C, void means "nothing" and if you have a return type of void that means you don't return anything.
But void* means pointer to nothing (...that i know about)... basically you get a pointer to something where you don't know what it is. But it's still a pointer, which is not nothing.
If you have a function that produces a value not via return but via parameter, you need to pass a pointer so that the function can set its value. You can do that via void* but that's unintentional. Consider the following wrong C code:
void var;
myFunc(&var);
myFunc would take a void* as parameter in order to fill its value, but a variable of type void is wrong because what would be its value. In correct C you would do it like that:
void* var = NULL;
myFunc(&var);
Here the type of var is clearly a pointer and its value is even initialised. For myFunc there's no real difference here, except that it'll now have a void** as parameter.
So if you modify ssh_pki_import_pubkey_file's declaration to have a void** parameter and change ssh_userauth_try_publickey's declaration to accept a void* parameter, you should be fine.

Call Library Function Node Error 1097

I'm pretty new to labview and I'm trying to use a Call Library Function Node to use a function from my library.
The function has the following prototype:
int function_name(int arg1, void* arg2, int* arg3, my_enum* arg4);
My call function nodes has 5 parameters, the return and the ones of the function that i have set in this way:
arg1, is a numeric I32;
arg2, is an array of U8 passed by value;
arg3, is a numeric I32 passed as a Pointer;
arg4, is a numeric I16 passed as a pointer;
My setup doesn't work, and i get an error 1097.
I'm pretty sure that the problem is with arg2, which is a pointer to a memory location in which the function will leave some data. How can I make it work?
I'm using LabView 2017, notice that arg2 and arg4 gets uploaded correctly.

Assigning primitives to NSManagedObject instance (Swift)

I am not able to make this work in storyboard:
Setup
// Extract an int from a (JSON) dictionary
let dict = ["eventId" : NSNumber(int:20)] as [String: AnyObject]
let eventId = dict["eventId"] as? Int
// Create managed object class
#objc(Event)
class Event : NSManagedObject {
#NSManaged var eventId: Int16 // as generated by Xcode
}
var event = Event()
Trying to assign a primitive to a Core Data object fails
event.eventId = eventId!
// Cannot assign a value of type 'Int' to a value of type 'Int16'
event.eventId = Int16(eventId!)
// Execution was interrupted, reason: signal SIGABRT.
event.eventId = Int32(eventId!)
// Cannot assign a value of type 'Int32' to a value of type 'Int16'
Sanity tests
eventId == nil // false
eventId == 0 // false
eventId! // 20
Int32(eventId!) // 20, transforming into Int32 seems to work
Int16(eventId!) // 20, transforming into Int16 seems to work
eventId is Int // true, but with weird warnings:
// Conditional cast from Int! to Int always succeeds
// 'is' test is always true
eventId is NSNumber // true, to my surprise! Only one warning:
// 'is' test is always true
More details
Note that casting the dictionary object to Int16 orInt32 returns nil.
Also, using let eventId = dict["eventId"]!.integerValue has the same results.
Defining the id as Int32 does not help either, the assignment fails.
This happens the same way in a proper project with full Core Data stack, including model, context, etc.
I have a hunch that it has to do with the way the instruction #NSManaged generates the accessors, but I do not know how to fix it without writing tons of more code.
Also, when I sometimes create a new project with Core Data from scratch it just works - but I cannot discern any differences. Let me know if you have any insights. My usual workaround is to not use primitives, but using NSNumber is sometimes less concise.
Instances of NSManagedObject must be created with the designated
initializer
init(entity:insertIntoManagedObjectContext:)
otherwise the Core Data accessor methods will not be created properly at runtime.
So this should work:
let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: context)!
let event = Event(entity: entity, insertIntoManagedObjectContext: context)
// Alternatively, use the equivalent "convenience method" from NSEntityDescription:
let event = NSEntityDescription.insertNewObjectForEntityForName("Entity", inManagedObjectContext: context) as! Event
event.eventId = Int16(eventId!)

How many arguments is a reasonable number, big objects vs atomic arguments. OOP

i'm a novel developer and i would like to know in yours experience what is the better approach when your building class methods, and if there is not a better approach, how balance your decisions with respect to:
Pass as arguments a big object that contains most of the variables needed for the method.
Pass the more atomic individuals variables possibles, with the consequences of generate methods with big signatures.
What is better for a code that is going to evolve? and what do you think is a reasonable number of arguments?
I would argue strongly in favor of passing around an object, if the commonality in the sets pf arguments allows it.
Why?
Because X% of effort goes to maintain existing code and it's a LOT harder to add new parameters - especially in methods that chain-call each other and pass those new parameters - than to add a property to an object.
Please note that this doesn't have to be a CLASS per se, in a sense of having methods. Merely a storage container (either a heterogeneous map/dictionary, or for type safety, a struct in C-type langages that support it).
Example (I'll use pseudocode, feel free which language(s) it's based on):
First, let's see old and new code using argument lists
Old code:
function f1(arg1, arg2, arg3, arg4, arg5) {
res = f2(arg1, arg2, arg3, arg4);
}
function f2(arg1, arg2, arg3, arg4) {
res = f3(arg1, arg2, arg4);
}
function f3(arg1, arg2, arg4) {
res = f4(arg1, arg4);
}
function f4(arg1, arg4) {
return arg1 + arg4;
}
New code (need to add arg6 in f4()):
function f1(arg1, arg2, arg3, arg4, arg5, arg6) { // changed line
res = f2(arg1, arg2, arg3, arg4, arg6); // changed line
}
function f2(arg1, arg2, arg3, arg4, arg6) { // changed line
res = f3(arg1, arg2, arg4, arg6); // changed line
}
function f3(arg1, arg2, arg4, arg6) { // changed line
res = f4(arg1, arg4, arg6); // changed line
}
function f4(arg1, arg4, arg6) { // changed line
return arg1 + arg4 + arg6; // changed line
}
As you can see, for 4-level nested calls, we changed ALL 4 functions, at the volume of at least 2 lines per function. YIKES. So for 10-level nested calls, adding 1 parameter changes all TEN functions and 20 lines.
Now, an example of the same change, except the arg list is now an object (or, for dynamic languages, a heterogeneous map would do :)
class args_class {
public:
int arg1, arg2, arg3, arg4, arg5;
}
}
args_class arg_object;
function f1(arg_object) {
res = f2(arg_object);
}
function f2(arg_object) {
res = f3(arg_object);
}
function f3(arg_object) {
res = f4(arg_object);
}
function f4(arg_object) {
return arg_object.arg1 + arg_object.arg4;
}
And what do we change to add arg6?
class args_class {
public:
int arg1, arg2, arg3, arg4, arg5, arg6; // line changed
}
}
// f1..f3 are unchanged
function f4(arg_object) {
return arg_object.arg1 + arg_object.arg4 + arg_object.arg6; // line changed
}
That's it. For 4-level nested methods, or for 10-level nested methods, you ONLY change 2 lines both.
Which one is less work to maintain?
I think it all depends on the context of the function parameters themselves. If you're relying on elements of some thing, then I'd pass a reference of that some thing as a parameter (whether it's a reference/pointer to an interface of that object or a reference/pointer to the object definition itself is an implementation detail).
If the parameter isn't derived directly from an object and there are a small number of parameters (five or less maybe? up to you really), then I'd pass atomic arguments.
If there are potentially a large number of arguments, then I'd create some sort of an init struct as a parameter, where the calling code instantiates and fills the struct and then passes a reference to it as an argument.

call c++ function with reference parameter from cli

The unmanaged function(pure c++, if that matters):
void fooC(float& result);
I define the wrapper as (managed wrapper, c++\cli):
void foo(float% result) //managed interface, need to pass result back to caller
{
fooC(???);//how to call unmanaged function?
}
how to pass reference parameter in the wrapper?
You can't convert a tracking reference to an unmanaged reference or pointer. The garbage collector would cause havoc when the passed float is a field in an object. You'll need to use a temporary:
void foo(float% result) {
float temp;
fooC(temp);
result = temp;
}