0

I am evaluating javonet to call a C# dll from java. As i see it's the more compliante to my context (generic fail with jni4net, and JnBridge don't export all my type)

I want to call a method with null instance on a complex generic.

System.Func<MyType<MySubType>, MyOtherType, MyAnotherType>

I try to call without generic but javonet don't find the method.

new NNull("System.Func")

I try to call with the return but javonet again don't find the method.

new NNull("System.Func`3[MyType`1[MySubType],MyOtherType,MyAnotherType]")

I don't find generic way to call NNull ? Is there any ?

Thanks by advance for any help ;o)

Shog9
  • 156,901
  • 35
  • 231
  • 235
Duff
  • 852
  • 12
  • 16
  • Hi, I am reproducing your case and will provide you the answer shortly, however please let me know if there is other overload of the method you are trying to call with the same number of arguments? – Przemysław Ładyński Sep 29 '16 at 14:31

1 Answers1

0

If there is only one method with matching number of arguments (no overloads) then you can easily pass "null".

However because the Javonet invoke(String, Object...) method expects method name and any number of params if you want to pass single argument null you must call obj.invoke("MethodName", new Object[] {null}); so Java knows that you pass single argument null not the null array what would mean no arguments at all.

In your case on .NET side:

public class ObjA
{
    public void MethodA(Func<MyType<MySubType>, MyOtherType, MyAnotherType>  arg)
    {
        Console.WriteLine("Called MethodA");
    }
}

public class MyType<T>
{

}
public class MySubType
{

}

public class MyOtherType
{

}

public class MyAnotherType
{

}

And to call it from Java using Javonet you make simply:

    NObject objA = Javonet.New("ObjA");
    objA.invoke("MethodA",new Object[] {null});

The NNull type is needed only if there is another method with the matching number of arguments when .NET cannot deduct from the null passed which method should be called. In example:

public void MethodA(Func<String> arg1);
public void MethodA(Func<int> arg1);

With multiple overloads

On the other hand if you have multiple overloads of the method with same number of arguments and want to pass null instead of your complex argument the same as in pure .NET you must cast null to the expected type:

public class ObjA
{
    public void MethodA(Func<MyType<MySubType>, MyOtherType, MyAnotherType> arg, int arg2)
    {
        Console.WriteLine("Called MethodA with args: Func<MyType<MySubType>, MyOtherType, MyAnotherType> arg, int arg2");
    }
    public void MethodA(Func<MyOtherType> arg, int arg2)
    {
        Console.WriteLine("Called MethodA with args: Func<MyOtherType> arg, int arg2");
    }
}

In .NET you would call:

MethodA((Func<MyType<MySubType>, MyOtherType, MyAnotherType>)null, 0);

You can still get the same done in Java using the Javonet 1.4hf26-SNAPSHOT release available here: http://download.javonet.com/1.4/javonet-1.4hf26-SNAPSHOT.jar

It is not official release but it is stable and can be used. That patch includes possibility to pass NType as argument to NNull object. In that case you would be able to construct your complex generic type with Javonet generic types creation syntax as in example below:

    NType myAnotherType = Javonet.getType("MyAnotherType");
    NType myOtherType = Javonet.getType("MyOtherType");
    NType mySubType = Javonet.getType("MySubType");
    NType myType = Javonet.getType("MyType`1",mySubType);
    NType func = Javonet.getType("Func`3",myType,myOtherType,myAnotherType);

    NObject objA = Javonet.New("ObjA");
    objA.invoke("MethodA",new NNull(func),0);
  • Sorry it's not working. In fact i have a lot of other arguments: – Duff Sep 29 '16 at 14:44
  • @Duff The other arguments should not cause any troubles. Can u paste me the signature of your method? If there are other methods with the same name and same number of arguments please pass me signatures for all of them and I will provide you the valid way to call it. – Przemysław Ładyński Sep 29 '16 at 14:46
  • Error : Available methods are: myNS.VariableContext GetInstance(myNS.RootBaseOneSourceNode, myNS.RootInstanceBaseOneSourceNode, myNS.ConfigurationOneSourceNode, myNS.CustomerOneSourceNode, myNS.VariableContext, System.Func`3[myNS.ReferenceOneSourceNode`1[myNS.VariableDeclarationOneSourceNode],myNS.VariableContext,myNS.VariableDeclarationOneSourceNode], Boolean, Boolean) ... – Duff Sep 29 '16 at 14:49
  • Java call : NObject varCtx = Javonet.getType("myNS.VariableContext").invoke("GetInstance", myComp, new NNull("myNS.RootInstanceBaseOneSourceNode"), new NNull("myNS.ConfigurationOneSourceNode"), new NNull("myNS.CustomerOneSourceNode"), new NNull("myNS.VariableContext"), new Object[] {null}, true, true); – Duff Sep 29 '16 at 14:50
  • @Duff those other arguments "*Node" are classes or enums? If there is only one "GetInstance" with 8 arguments (no overloads then you should be able to call it like this: Javonet.getType("myNS.VariableContext").invoke("GetInstance"‌​, myComp, null, null,null,null,null,true,true); Without using "NNulls" did you try in this way? Or do you have more overloads of GetInstance with 8 arguments? – Przemysław Ładyński Sep 29 '16 at 14:53
  • Can add also to your question the exact error message that you get from Javonet? – Przemysław Ładyński Sep 29 '16 at 15:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/124558/discussion-between-przemyslaw-ladynski-and-duff). – Przemysław Ładyński Sep 29 '16 at 15:06
  • i have no other with 8 so before your ask i already try it, and it's not work. But i replace my first arg (myComp) by null and he found my method (NullPointer in it but it's normal ;o) . So i try to found the real dll type of my instance now to understand what NType i have... – Duff Sep 29 '16 at 15:07