Jump to content
fcknbstrd

the return type of CallVoidMethodV does not match void

Recommended Posts

Hello,

 

I'm getting an error log message (Android Device Monitor) in my Android app built with Delphi 10.3.2, tested on a Nokia 7 (Android 9) and NVIDIA Shield K1 tablet (Android 7):

java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: the return type of CallVoidMethodV does not match void cn.easyar.FunctorOfVoidFromTargetAndBool.invoke(cn.easyar.Target, boolean)

I'm building an AR framework with an external library and it crashes when I try to load an image target for AR detection.

The weird thing is: that I have an older project (created with 10.3.1) where the framework runs successfully, ... but only on the Shield tablet (Android 7).

But when creating a new project with 10.3.2 my framework do not run on any device.

 

Is there any difference in project files, that could have influence?

The method signature seems okey to me for a CallVoidMethodV call.

 

 

The interface is declared in third party JAR as:

package cn.easyar;

public interface FunctorOfVoidFromTargetAndBool {
  void invoke(Target paramTarget, boolean paramBoolean);
}

The interface declaration in Delphi JNI file, looks like:

JFunctorOfVoidFromTargetAndBoolClass = interface(IJavaClass)
  ['{A269080B-630F-428F-987C-B8B611A82E57}']
end;

[JavaSignature('cn/easyar/FunctorOfVoidFromTargetAndBool')]
JFunctorOfVoidFromTargetAndBool = interface(IJavaInstance)
  ['{CA02CD6D-7C69-43CA-B5C4-53C65761EEA0}']
  {class} procedure invoke(P1: Jeasyar_Target; P2: Boolean); cdecl;
end;
TJFunctorOfVoidFromTargetAndBool = class(TJavaGenericImport<JFunctorOfVoidFromTargetAndBoolClass, JFunctorOfVoidFromTargetAndBool>) end;

It seems to be a callback, so I declared a TJavaLocal, like this:


TFunctorOfVoidFromTargetAndBoolProxy = class(TJavaLocal, JFunctorOfVoidFromTargetAndBool)
  protected
  public
    constructor Create();

    { JFunctorOfVoidFromTargetAndBool }
    procedure invoke(P1: Jeasyar_Target; P2: Boolean); cdecl;
end;

{ Implementation of JavaLocal }
  
constructor TFunctorOfVoidFromTargetAndBoolProxy.Create();
begin
  inherited Create();
end;

procedure TFunctorOfVoidFromTargetAndBoolProxy.invoke(P1: Jeasyar_Target;
  P2: Boolean); cdecl;
begin
  if P2 then
    FMX.Types.Log.D('target ' + JStringToString(P1.name) + ' loaded')
  else
    FMX.Types.Log.D('failed to load target ' + JStringToString(P1.name));
end;

The functor is getting used the following way:

FOnLoadTarget := TJFunctorOfVoidFromTargetAndBool.Wrap(
	(TFunctorOfVoidFromTargetAndBoolProxy.Create() as ILocalObject).GetObjectID()
	);

// loading the target with callback
FTracker.LoadTarget(FTarget, FScheduler, FOnLoadTarget);

Used fields are declared like that:

// field declarations
[...]
FScheduler : JDelayedCallbackScheduler; // inherited from JCallbackScheduler
FTracker : JImageTracker;
FTarget : JImageTarget; // inherited from Jeasyar_Target
FOnLoadTarget : JFunctorOfVoidFromTargetAndBool;
[...]

 

The tracker "loadTarget" method is declared as:

  JImageTrackerClass = interface(JRefBaseClass)
    ['{CCD92F4A-618D-420A-8AF5-240051B51A73}']
    {...}
  end;

  [JavaSignature('cn/easyar/ImageTracker')]
  JImageTracker = interface(JRefBase)
    ['{CD917C43-91DD-4602-9683-82EFC85F5988}']
    {...}
    procedure loadTarget(P1: Jeasyar_Target; P2: JCallbackScheduler; P3: JFunctorOfVoidFromTargetAndBool); cdecl;
    {...}
  end;
  TJImageTracker = class(TJavaGenericImport<JImageTrackerClass, JImageTracker>) end;

Remarks: The "loadTarget" method is loading an image file as target asynchronously in a separate thread.

 

 

I would be pleased if anyone has an idea on that, because I'm stucked for a while now :)

 

(Notice: I attached the complete logfile output for more details.)

log-nokia2.txt

Share this post


Link to post

I found a solution myself. I've built a separate JavaClass lib which accesses the AR-JAR.

I call loadTarget() inside of Java, to prevent creating a TJavaLocal in Delphi.

 

There seems to be a problem with TJavaLocal (ProxyInterface / InvocationHandler) in new compilers.

Because the 3rd party AR-suite declares callback interfaces with an "invoke" callback method:

 

package cn.easyar;

public interface FunctorOfVoidFromTargetAndBool {
  void invoke(Target paramTarget, boolean paramBoolean);
}

The call on FunctorOfVoidFromTargetAndBool.invoke (performed by the 3rd party library, using JNI) leads to a method collision, because InvocationHandler itself declares also an "invoke" method.

JNI picks the wrong "invoke" method which leads to the error message:

java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: the return type of CallVoidMethodV does not match void cn.easyar.FunctorOfVoidFromTargetAndBool.invoke(cn.easyar.Target, boolean)

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×