问题描述:

I'm developing a mobile app using C++ Builder Berlin 10.1 which use a Jar library to scan barcodes. With Java2OP, I obtained a Delphi Bridge File to use the functions of the Jar. I translated it to C++ and include it to my project with the associated Jar. Here are my files:

Delphi:

{*******************************************************}

{ }

{ CodeGear Delphi Runtime Library }

{ Copyright(c) 2014 Embarcadero Technologies, Inc. }

{ }

{*******************************************************}

unit Android.JNI.ATScanLib;

interface

uses

Androidapi.JNIBridge,

Androidapi.JNI.JavaTypes;

type

// ===== Forward declarations =====

JAsyncTask = interface;//android.os.AsyncTask

JAsyncTask_Status = interface;//android.os.AsyncTask$Status

JATScanLib = interface;//com.atid.lib.ATScanLib

JATScanLib_OnResponseListener = interface;//com.atid.lib.ATScanLib$OnResponseListener

JATScanLib_TagSequenceTask = interface;//com.atid.lib.ATScanLib$TagSequenceTask

JVoid = interface;//java.lang.Void

// ===== Interface declarations =====

JAsyncTaskClass = interface(JObjectClass)

['{73C141D6-F8D7-4FE4-BFA3-3441B6367189}']

{class} function _GetSERIAL_EXECUTOR: JExecutor;

{class} function _GetTHREAD_POOL_EXECUTOR: JExecutor;

{class} function init: JAsyncTask; cdecl;

{class} procedure execute(runnable: JRunnable); cdecl; overload;

{class} property SERIAL_EXECUTOR: JExecutor read _GetSERIAL_EXECUTOR;

{class} property THREAD_POOL_EXECUTOR: JExecutor read _GetTHREAD_POOL_EXECUTOR;

end;

[JavaSignature('android/os/AsyncTask')]

JAsyncTask = interface(JObject)

['{8BC49850-F199-4620-BCFF-ACDA1D69417A}']

function cancel(mayInterruptIfRunning: Boolean): Boolean; cdecl;

function &get: JObject; cdecl; overload;

function &get(timeout: Int64; unit_: JTimeUnit): JObject; cdecl; overload;

function getStatus: JAsyncTask_Status; cdecl;

function isCancelled: Boolean; cdecl;

end;

TJAsyncTask = class(TJavaGenericImport<JAsyncTaskClass, JAsyncTask>) end;

JAsyncTask_StatusClass = interface(JEnumClass)

['{16452E24-44D5-4E84-990E-3C1916FB372B}']

{class} function _GetFINISHED: JAsyncTask_Status;

{class} function _GetPENDING: JAsyncTask_Status;

{class} function _GetRUNNING: JAsyncTask_Status;

{class} function valueOf(name: JString): JAsyncTask_Status; cdecl;

{class} function values: TJavaObjectArray<JAsyncTask_Status>; cdecl;

{class} property FINISHED: JAsyncTask_Status read _GetFINISHED;

{class} property PENDING: JAsyncTask_Status read _GetPENDING;

{class} property RUNNING: JAsyncTask_Status read _GetRUNNING;

end;

[JavaSignature('android/os/AsyncTask$Status')]

JAsyncTask_Status = interface(JEnum)

['{96B0BCE7-1312-49B9-9F33-43541680B0E7}']

end;

TJAsyncTask_Status = class(TJavaGenericImport<JAsyncTask_StatusClass, JAsyncTask_Status>) end;

JATScanLibClass = interface(JObjectClass)

['{9A209D1D-07C6-4309-88AD-8A2EF359CF34}']

{class} function _GetREAD_ENCODING_ERROR: Integer;

{class} function _GetREAD_ERROR: Integer;

{class} function _GetREAD_OK: Integer;

{class} function _GetREAD_TIMEOUT: Integer;

{class} function init: JATScanLib; cdecl;

{class} property READ_ENCODING_ERROR: Integer read _GetREAD_ENCODING_ERROR;

{class} property READ_ERROR: Integer read _GetREAD_ERROR;

{class} property READ_OK: Integer read _GetREAD_OK;

{class} property READ_TIMEOUT: Integer read _GetREAD_TIMEOUT;

end;

[JavaSignature('com/atid/lib/ATScanLib')]

JATScanLib = interface(JObject)

['{74B37E9E-F88A-4EB0-AEDF-538A472223A0}']

function Read(P1: TJavaArray<Byte>): Integer; cdecl;

function getReadResults: JString; cdecl;

procedure init; cdecl;

procedure setEncoding(P1: JString); cdecl;

procedure setOnResponseListener(P1: JATScanLib_OnResponseListener); cdecl;

procedure start; cdecl;

procedure stop; cdecl;

end;

TJATScanLib = class(TJavaGenericImport<JATScanLibClass, JATScanLib>) end;

JATScanLib_OnResponseListenerClass = interface(IJavaClass)

['{654B87BA-B4EE-4102-85E9-9FDFF3C82BAA}']

end;

[JavaSignature('com/atid/lib/ATScanLib$OnResponseListener')]

JATScanLib_OnResponseListener = interface(IJavaInstance)

['{35AC182B-7684-47EA-9BA8-07B504F85943}']

procedure onResponse(P1: Integer); cdecl;

end;

TJATScanLib_OnResponseListener = class(TJavaGenericImport<JATScanLib_OnResponseListenerClass, JATScanLib_OnResponseListener>) end;

JATScanLib_TagSequenceTaskClass = interface(JAsyncTaskClass)

['{1CF84DF6-6115-4FB5-9967-B55E74A3155C}']

end;

[JavaSignature('com/atid/lib/ATScanLib$TagSequenceTask')]

JATScanLib_TagSequenceTask = interface(JAsyncTask)

['{B83D8A9F-C1C4-4023-B1D8-3D9ABFB1FD2C}']

end;

TJATScanLib_TagSequenceTask = class(TJavaGenericImport<JATScanLib_TagSequenceTaskClass, JATScanLib_TagSequenceTask>) end;

JVoidClass = interface(JObjectClass)

['{E5AB6B2B-2580-469B-BBF6-C226984DFEBE}']

{class} function _GetTYPE: Jlang_Class;

{class} property &TYPE: Jlang_Class read _GetTYPE;

end;

[JavaSignature('java/lang/Void')]

JVoid = interface(JObject)

['{013CC63A-938C-46BE-ACAC-BA854F2F6AC8}']

end;

TJVoid = class(TJavaGenericImport<JVoidClass, JVoid>) end;

implementation

procedure RegisterTypes;

begin

TRegTypes.RegisterType('Android.JNI.ATScanLib.JAsyncTask', TypeInfo(Android.JNI.ATScanLib.JAsyncTask));

TRegTypes.RegisterType('Android.JNI.ATScanLib.JAsyncTask_Status', TypeInfo(Android.JNI.ATScanLib.JAsyncTask_Status));

TRegTypes.RegisterType('Android.JNI.ATScanLib.JATScanLib', TypeInfo(Android.JNI.ATScanLib.JATScanLib));

TRegTypes.RegisterType('Android.JNI.ATScanLib.JATScanLib_OnResponseListener', TypeInfo(Android.JNI.ATScanLib.JATScanLib_OnResponseListener));

TRegTypes.RegisterType('Android.JNI.ATScanLib.JATScanLib_TagSequenceTask', TypeInfo(Android.JNI.ATScanLib.JATScanLib_TagSequenceTask));

TRegTypes.RegisterType('Android.JNI.ATScanLib.JVoid', TypeInfo(Android.JNI.ATScanLib.JVoid));

end;

initialization

RegisterTypes;

end.

C++:

#ifndef Android_JNI_ATScanLibH

#define Android_JNI_ATScanLibH

#pragma delphiheader begin

#pragma option push

#pragma option -w- // All warnings off

#pragma option -Vx // Zero-length empty class member

#pragma pack(push,8)

#include <Androidapi.JNIBridge.hpp>

#include <Androidapi.JNI.JavaTypes.hpp>

#include <System.hpp>

#include <SysInit.hpp>

namespace Android{

namespace Jni{

namespace Atscanlib{

__interface JAsyncTask;

typedef System::DelphiInterface<JAsyncTask> _di_JAsyncTask;

__interface JAsyncTaskClass;

typedef System::DelphiInterface<JAsyncTaskClass> _di_JAsyncTaskClass;

__interface JAsyncTask_Status;

typedef System::DelphiInterface<JAsyncTask_Status> _di_JAsyncTask_Status;

__interface JAsyncTask_StatusClass;

typedef System::DelphiInterface<JAsyncTask_StatusClass> _di_JAsyncTask_StatusClass;

__interface JATScanLib;

typedef System::DelphiInterface<JATScanLib> _di_JATScanLib;

__interface JATScanLibClass;

typedef System::DelphiInterface<JATScanLibClass> _di_JATScanLibClass;

__interface JATScanLib_OnResponseListener;

typedef System::DelphiInterface<JATScanLib_OnResponseListener> _di_JATScanLib_OnResponseListener;

__interface JATScanLib_OnResponseListenerClass;

typedef System::DelphiInterface<JATScanLib_OnResponseListenerClass> _di_JATScanLib_OnResponseListenerClass;

__interface JATScanLib_TagSequenceTask;

typedef System::DelphiInterface<JATScanLib_TagSequenceTask> _di_JATScanLib_TagSequenceTask;

__interface JATScanLib_TagSequenceTaskClass;

typedef System::DelphiInterface<JATScanLib_TagSequenceTask> _di_JATScanLib_TagSequenceTaskClass;

__interface JVoid;

typedef System::DelphiInterface<JVoid> _di_JVoid;

__interface JVoidClass;

typedef System::DelphiInterface<JVoid> _di_JVoidClass;

__interface INTERFACE_UUID("{73C141D6-F8D7-4FE4-BFA3-3441B6367189}") JAsyncTaskClass : public Androidapi::Jni::Javatypes::JObjectClass

{

public:

virtual JExecutor _GetSERIAL_EXECUTOR() = 0;

virtual JExecutor _GetTHREAD_POOL_EXECUTOR() = 0;

HIDESBASE virtual _di_JAsyncTask __cdecl init() = 0;

virtual void __cdecl execute(JRunnable runnable) = 0;

__property JExecutor SERIAL_EXECUTOR = {read = _GetSERIAL_EXECUTOR};

__property JExecutor THREAD_POOL_EXECUTOR = {read = _GetTHREAD_POOL_EXECUTOR};

};

__interface INTERFACE_UUID("{73C141D6-F8D7-4FE4-BFA3-3441B6367189}") JAsyncTask : public Androidapi::Jni::Javatypes::JObject

{

public:

virtual bool __cdecl cancel(bool mayInterruptIfRunning) = 0;

virtual JObject __cdecl get() = 0;

virtual JObject __cdecl get(__int64 timeout, JTimeUnit unit_) = 0;

virtual _di_JAsyncTask_Status __cdecl getStatus() = 0;

virtual bool __cdecl isCancelled() = 0;

};

#pragma pack(push,4)

class PASCALIMPLEMENTATION TJAsyncTask : public Androidapi::Jnibridge::TJavaGenericImport__2<_di_JAsyncTaskClass, _di_JAsyncTask>{

typedef Androidapi::Jnibridge::TJavaGenericImport__2<_di_JAsyncTaskClass, _di_JAsyncTask> inherited;

public:

inline __fastcall TJAsyncTask(void) : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JAsyncTaskClass, _di_JAsyncTask> (){}

inline __fastcall virtual ~TJAsyncTask(void){}

};

#pragma pack(pop)

__interface INTERFACE_UUID("{16452E24-44D5-4E84-990E-3C1916FB372B}") JAsyncTask_StatusClass : public Androidapi::Jni::Javatypes::JEnumClass

{

public:

virtual _di_JAsyncTask_Status _GetFINISHED() = 0;

virtual _di_JAsyncTask_Status _GetPENDING() = 0;

virtual _di_JAsyncTask_Status _GetRUNNING() = 0;

virtual _di_JAsyncTask_Status __cdecl valueOf(JString name) = 0;

virtual TJavaObjectArray__1<_di_JAsyncTask_Status> __cdecl values() = 0;

__property _di_JAsyncTask_Status FINISHED = {read = _GetFINISHED};

__property _di_JAsyncTask_Status PENDING = {read = _GetPENDING};

__property _di_JAsyncTask_Status RUNNING = {read = _GetRUNNING};

};

__interface INTERFACE_UUID("{96B0BCE7-1312-49B9-9F33-43541680B0E7}") JAsyncTask_Status : public Androidapi::Jni::Javatypes::JEnum

{

};

#pragma pack(push,4)

class PASCALIMPLEMENTATION TJAsyncTask_Status : public Androidapi::Jnibridge::TJavaGenericImport__2<_di_JAsyncTask_StatusClass, _di_JAsyncTask_Status>{

typedef Androidapi::Jnibridge::TJavaGenericImport__2<_di_JAsyncTask_StatusClass, _di_JAsyncTask_Status> inherited;

public:

inline __fastcall TJAsyncTask_Status(void) : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JAsyncTask_StatusClass, _di_JAsyncTask_Status> (){}

inline __fastcall virtual ~TJAsyncTask_Status(void){}

};

#pragma pack(pop)

__interface INTERFACE_UUID("{9A209D1D-07C6-4309-88AD-8A2EF359CF34}") JATScanLibClass : public Androidapi::Jni::Javatypes::JObjectClass

{

public:

virtual int _GetREAD_ENCODING_ERROR() = 0;

virtual int _GetREAD_ERROR() = 0;

virtual int _GetREAD_OK() = 0;

virtual int _GetREAD_TIMEOUT() = 0;

HIDESBASE virtual _di_JATScanLib __cdecl init() = 0;

__property int READ_ENCODING_ERROR = {read = _GetREAD_ENCODING_ERROR};

__property int READ_ERROR = {read = _GetREAD_ERROR};

__property int READ_OK = {read = _GetREAD_OK};

__property int READ_TIMEOUT = {read = _GetREAD_TIMEOUT};

};

__interface INTERFACE_UUID("{74B37E9E-F88A-4EB0-AEDF-538A472223A0}") JATScanLib : public Androidapi::Jni::Javatypes::JObject

{

public:

virtual int __cdecl Read(TJavaArray__1<Byte> P1) = 0;

virtual JString __cdecl getReadResults() = 0;

virtual void __cdecl init() = 0;

virtual void __cdecl setEncoding(JString P1) = 0;

virtual void __cdecl setOnResponseListener(_di_JATScanLib_OnResponseListener P1) = 0;

virtual void __cdecl start() = 0;

virtual void __cdecl stop() = 0;

};

#pragma pack(push,4)

class PASCALIMPLEMENTATION TJATScanLib : public Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLibClass, _di_JATScanLib>{

typedef Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLibClass, _di_JATScanLib> inherited;

public:

inline __fastcall TJATScanLib(void) : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLibClass, _di_JATScanLib> (){}

inline __fastcall virtual ~TJATScanLib(void){}

};

#pragma pack(pop)

__interface INTERFACE_UUID("{654B87BA-B4EE-4102-85E9-9FDFF3C82BAA}") JATScanLib_OnResponseListenerClass : public Androidapi::Jnibridge::IJavaClass

{

};

__interface INTERFACE_UUID("{35AC182B-7684-47EA-9BA8-07B504F85943}") JATScanLib_OnResponseListener : public Androidapi::Jnibridge::IJavaInstance

{

public:

virtual void __cdecl onResponse(int P1) = 0;

};

#pragma pack(push,4)

class PASCALIMPLEMENTATION TJATScanLib_OnResponseListener : public Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLib_OnResponseListenerClass, _di_JATScanLib_OnResponseListener>{

typedef Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLib_OnResponseListenerClass, _di_JATScanLib_OnResponseListener> inherited;

public:

inline __fastcall TJATScanLib_OnResponseListener(void) : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLib_OnResponseListenerClass, _di_JATScanLib_OnResponseListener> (){}

inline __fastcall virtual ~TJATScanLib_OnResponseListener(void){}

};

#pragma pack(pop)

__interface INTERFACE_UUID("{1CF84DF6-6115-4FB5-9967-B55E74A3155C}") JATScanLib_TagSequenceTaskClass : public _di_JAsyncTaskClass

{

};

__interface INTERFACE_UUID("{B83D8A9F-C1C4-4023-B1D8-3D9ABFB1FD2C}") JATScanLib_TagSequenceTask : public _di_JAsyncTask

{

};

#pragma pack(push,4)

class PASCALIMPLEMENTATION TJATScanLib_TagSequenceTask : public Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLib_TagSequenceTaskClass, _di_JATScanLib_TagSequenceTask>{

typedef Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLib_TagSequenceTaskClass, _di_JATScanLib_TagSequenceTask> inherited;

public:

inline __fastcall TJATScanLib_TagSequenceTask(void) : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLib_TagSequenceTaskClass, _di_JATScanLib_TagSequenceTask> (){}

inline __fastcall virtual ~TJATScanLib_TagSequenceTask(void){}

};

#pragma pack(pop)

__interface INTERFACE_UUID("{E5AB6B2B-2580-469B-BBF6-C226984DFEBE}") JVoidClass : public Androidapi::Jni::Javatypes::JObjectClass

{

public:

virtual Jlang_Class _GetTYPE() = 0;

__property Jlang_Class TYPE = {read = _GetTYPE};

};

__interface INTERFACE_UUID("{013CC63A-938C-46BE-ACAC-BA854F2F6AC8}") JVoid : public Androidapi::Jni::Javatypes::JObject

{

};

#pragma pack(push,4)

class PASCALIMPLEMENTATION TJVoid : public Androidapi::Jnibridge::TJavaGenericImport__2<_di_JVoidClass, _di_JVoid>{

typedef Androidapi::Jnibridge::TJavaGenericImport__2<_di_JVoidClass, _di_JVoid> inherited;

public:

inline __fastcall TJVoid(void) : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JVoidClass, _di_JVoid> (){}

inline __fastcall virtual ~TJVoid(void){}

};

#pragma pack(pop)

}

}

}

#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROID_JNI_ATLIB)

using namespace Android::Jni::Atscanlib;

#endif

#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROID_JNI)

using namespace Android::Jni;

#endif

#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROID)

using namespace Android;

#endif

#pragma pack(pop)

#pragma option pop

#pragma delphiheader end.

#endif

When I tried to use the functions like this :

TJATScanLib* scan = new TJATScanLib();

_di_JATScanLibClass scanner = TJATScanLib::JavaClass->init();

C++ Builder raised this link error :

[ldandroid Erreur] C:\Users\Public\Documents\Embarcadero\Studio\18.0\CatalogRepository\AndroidNDK-9c_x86_GIB.Build.22858.6822\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-ld.exe: .\Android\Debug\Connexion.o: in function TForm_Connexion::TForm_Connexion(System::Classes::TComponent*):C:\Users\dylan\Documents\Embarcadero\Studio\Projets\PDA_Android/Connexion.cpp:28:error:

undefined reference to 'Androidapi::Jnibridge::TJavaGenericImport__2, System::DelphiInterface >::GetJavaClass()'

and

[ldandroid Erreur] C:\Users\Public\Documents\Embarcadero\Studio\18.0\CatalogRepository\AndroidNDK-9c_x86_GIB.Build.22858.6822\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-ld.exe: .\Android\Debug\Connexion.o: in function TForm_Connexion::TForm_Connexion(System::Classes::TComponent*):C:\Users\dylan\Documents\Embarcadero\Studio\Projets\PDA_Android/Connexion.cpp:30:error:

undefined reference to 'vtable for Android::Jni::Atscanlib::TJATScanLib'

Did I use the function in the wrong way?

网友答案:

I had a response from Embarcadero. I had some files which are missing from the IDE. Here are the steps to follow:

  • In C++ Builder, go to Project/Options/Delphi Compiler/Search path
  • Enter "$(BDSLIB)\$(PLATFORM)\Release;$(BDSLIB)\$(PLATFORM)\Debug" (without the quotes)
  • Save the project and THEN try the command line build (MSBuild /v:diag XXXX.cbproj)

If it still doesn't work, the Support sent me some bpl, jdgb and de files to copy in the Bin directory and two register to add. Unfortunately, I can't attach these files to a post. If you want these files, give me your mail address and I'll send them to you. If you have the files, here are the other steps:

  • Unzip the files(Link to this post) to your \Bin directory
  • Shut the IDE
  • run regedit
  • Go to : HKEY_CURRENT_USER\Software\Embarcadero\BDS\18.0\Known IDE Packages
  • add a string value with the name "$(BDS)\Bin\delphiandroid32240.bpl" and value "Delphi Android Platform" (both without the quotes)
  • Then go to: "HKEY_CURRENT_USER\Software\Embarcadero\BDS\18.0\Known IDE Packages\Delphi"
  • Add "$(BDS)\Bin\delphiandroidservices240.bpl" and value of "Delphi Android Services"
  • Start the IDE, you should now have the Delphi android support in the IDE so project should hopefully compile in IDE.

If it compiles but doesn't generate the HPP file:

  • Go to Project/Options/Delphi Compiler/ C/C++ output
  • Select "Generate C++ .objs, headers, namespaces, export"

I hope it will help others who are in my case.

相关阅读:
Top