【问题标题】:Implement Java interface (bridged through Delphi) in C++在 C++ 中实现 Java 接口(通过 Delphi 桥接)
【发布时间】:2018-04-30 10:06:24
【问题描述】:

我想实现一个 Java 接口(通过 Delphi 与 Java2OP 桥接)并在 C++ 中覆盖它的方法。

这之前在我的项目中使用另一个 Java SDK 成功完成,方法如下所示,我复制了(2 个持续的代码块)。

这编译正确,但我在运行时得到EJNI error"onScanComplete method not found"

另一个问题是,如果我尝试实例化 TJBarcode2DWithSoft_ScanCallback 类并将其提供给 TJBarcode2DWithSoft->setScanCallback(_di_JBarcode2DWithSoft_ScanCallback),我总是会收到错误消息:

ScanManager.cpp(147): no matching conversion for functional-style cast from 'Mca::Dev::Api::TJBarcode2DWithSoft_ScanCallback' to '_di_JBarcode2DWithSoft_ScanCallback' (aka 'DelphiInterface<Mca::Dev::Api::JBarcode2DWithSoft_ScanCallback>')
  systobj.h(261): candidate constructor not viable: no known conversion from 'Mca::Dev::Api::TJBarcode2DWithSoft_ScanCallback' to 'const DelphiInterface<Mca::Dev::Api::JBarcode2DWithSoft_ScanCallback>' for 1st argument
  systobj.h(268): candidate constructor not viable: no known conversion from 'Mca::Dev::Api::TJBarcode2DWithSoft_ScanCallback' to 'Mca::Dev::Api::JBarcode2DWithSoft_ScanCallback *' for 1st argument
  systobj.h(254): candidate template ignored: could not match 'DelphiInterface<type-parameter-0-0>' against 'Mca::Dev::Api::TJBarcode2DWithSoft_ScanCallback'
  systobj.h(278): candidate template ignored: disabled by 'enable_if' [with TArg = Mca::Dev::Api::TJBarcode2DWithSoft_ScanCallback &]
  systobj.h(248): candidate constructor not viable: requires 0 arguments, but 1 was provided

我想知道我是否可以像在 Java 中一样在 C++ 中使用本地类来完成所有这些操作,而无需通过 Delphi。

SDK 中的 ScanCallBack 定义:

public class Barcode2DWithSoft {
    ...
    public interface ScanCallback {
            void onScanComplete(int var1, int var2, byte[] var3);
    }
}

Java项目方式覆盖ScanCallback接口方法(无错误):

public Barcode2DWithSoft.ScanCallback  ScanBack= new Barcode2DWithSoft.ScanCallback(){
        @Override
        public void onScanComplete(int i, int length, byte[] bytes) {
              //Code Executed on Event
        }
    };

private void ScanBarcode(){
    barcode2DWithSoft.scan();
    barcode2DWithSoft.setScanCallback(ScanBack);
}


在 Delphi 中使用的方法:ScanCallBack.pas

type
  TNotifyScanCompleteEvent = procedure(P1: Integer; P2: Integer; P3: TJavaArray<Byte>) of object;

  TAJBarcode2DWithSoft_ScanCallback = class(TJavaLocal, JBarcode2DWithSoft_ScanCallback)
   FOnScanComplet : TNotifyScanCompleteEvent;
  public
    procedure onScanComplete(P1: Integer; P2: Integer; P3: TJavaArray<Byte>); virtual; cdecl;
    property OnScanComplet: TNotifyScanCompleteEvent read FOnScanComplet write FOnScanComplet;
  end;

implementation
{ TAJBarcode2DWithSoft_ScanCallback }

procedure TAJBarcode2DWithSoft_ScanCallback.onScanComplete(P1: Integer; P2: Integer; P3: TJavaArray<Byte>);
begin
  if Assigned(FOnScanComplet) then FOnScanComplet(P1,P2,P3);
end;

在我的 C++ 项目中使用时

TAJBarcode2DWithSoft_ScanCallback * ScanListener = new TAJBarcode2DWithSoft_ScanCallback();
ScanListener->OnScanComplet = mca5OnScanCallBack;
this->ScanMCA5->setScanCallback(_di_JBarcode2DWithSoft_ScanCallback(*ScanListener));


编辑:

Java2OP 自动生成的 JBarcode2DWithSoft_ScanCallback 定义(Barcode2DWithSoft.ScanCallBack 的桥):

  JBarcode2DWithSoft_ScanCallbackClass = interface(IJavaClass)
    ['{CC4376C0-AB56-4CE0-9612-C947DAE2160F}']
   {class} procedure onScanComplete(P1: Integer; P2: Integer; P3: TJavaArray<Byte>); cdecl;//Deprecated
  end;

  [JavaSignature('com/zebra/adc/decoder/Barcode2DWithSoft$ScanCallback')]
  JBarcode2DWithSoft_ScanCallback = interface(IJavaInstance)
    ['{202711EC-3B53-469F-B6CD-C8428226565D}']
  end;
  TJBarcode2DWithSoft_ScanCallback = class(TJavaGenericImport<JBarcode2DWithSoft_ScanCallbackClass, JBarcode2DWithSoft_ScanCallback>) end;

【问题讨论】:

  • 其中一个考虑的函数提到了const - 我想知道这是否是问题所在?不知道你...
  • 这可以在没有 Delphi 桥的情况下完成
  • 你没有包含定义JBarcode2DWithSoft_ScanCallback的代码
  • @DaveNottage 好的,我在编辑中添加了它。我想知道它是否可以提供帮助,因为它只是 Java 接口的自动生成桥。

标签: java android delphi c++builder


【解决方案1】:

JBarcode2DWithSoft_ScanCallback 的定义自动生成不正确。它应该是这样的:

  JBarcode2DWithSoft_ScanCallbackClass = interface(IJavaClass)
    ['{CC4376C0-AB56-4CE0-9612-C947DAE2160F}']
  end;

  [JavaSignature('com/zebra/adc/decoder/Barcode2DWithSoft$ScanCallback')]
  JBarcode2DWithSoft_ScanCallback = interface(IJavaInstance)
    ['{202711EC-3B53-469F-B6CD-C8428226565D}']
    procedure onScanComplete(P1: Integer; P2: Integer; P3: TJavaArray<Byte>); cdecl;
  end;

  TJBarcode2DWithSoft_ScanCallback = class(TJavaGenericImport<JBarcode2DWithSoft_ScanCallbackClass, JBarcode2DWithSoft_ScanCallback>) end;

【讨论】:

  • 是的,我看到了,也觉得这很奇怪。我改变了它,但我仍然在运行时得到EJNI error"can't find onScanComplete method"。我不明白为什么我不能将TJBarcode2DWithSoft_ScanCallback 转换为_di_JBarcode2DWithSoft_ScanCallback,尽管它实现了JBarcode2DWithSoft_ScanCallback 接口。如果我可以使用它,我不需要自己在 Delphi 中创建这样的类,将其更改为 onScanComplete() 方法并将其提供给需要 _di_JBarcode2DWithSoft_ScanCallbacksetScan()
  • 提供调用堆栈可能会有所帮助
  • 错误在Androidapi.JNIBridge.pasAndroidapi.JNIBridge.pas的第651行被抛出:" raise EJNIFatal.CreateResFmt(@SJNIMethodNotFound, 'onScanComplete'); "它在类Barcode2DWithSoft中被这样的行调用,在另一个线程中执行:case 2: if(Barcode2DWithSoft.this.scanCallback != null) { temp = new byte[1]; Barcode2DWithSoft.this.scanCallback.onScanComplete(-1, msg.arg1, temp); }所以@我给它的 987654334@ 实例不会包含 onScanComplete 方法。
  • 虽然Barcode2DWithSoft.setScanCallback() 方法确实收到了ScanCallback 实例public synchronized void setScanCallback(final Barcode2DWithSoft.ScanCallback sc) {}
  • 我的意思是一个完整的调用栈,而不是最后一行。此外,您对案例 2 的第二条最后评论中的代码:似乎正在尝试调用由侦听器实现的方法,您不应直接调用该方法;这应该由扫描仪实例调用。
猜你喜欢
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-06
  • 1970-01-01
相关资源
最近更新 更多