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) 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 ; 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 ) 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 ): 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 ) 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 ) 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 ) 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 ) 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_ATScanLibHPP #define Android_JNI_ATScanLibHPP #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#include #include #include namespace Android{ namespace Jni{ namespace Atscanlib{ __interface JAsyncTask; typedef System::DelphiInterface _di_JAsyncTask; __interface JAsyncTaskClass; typedef System::DelphiInterface _di_JAsyncTaskClass; __interface JAsyncTask_Status; typedef System::DelphiInterface _di_JAsyncTask_Status; __interface JAsyncTask_StatusClass; typedef System::DelphiInterface _di_JAsyncTask_StatusClass; __interface JATScanLib; typedef System::DelphiInterface _di_JATScanLib; __interface JATScanLibClass; typedef System::DelphiInterface _di_JATScanLibClass; __interface JATScanLib_OnResponseListener; typedef System::DelphiInterface _di_JATScanLib_OnResponseListener; __interface JATScanLib_OnResponseListenerClass; typedef System::DelphiInterface _di_JATScanLib_OnResponseListenerClass; __interface JATScanLib_TagSequenceTask; typedef System::DelphiInterface _di_JATScanLib_TagSequenceTask; __interface JATScanLib_TagSequenceTaskClass; typedef System::DelphiInterface _di_JATScanLib_TagSequenceTaskClass; __interface JVoid; typedef System::DelphiInterface _di_JVoid; __interface JVoidClass; typedef System::DelphiInterface _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; }; class DELPHICLASS TJAsyncTask; #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 { }; class DELPHICLASS TJAsyncTask_Status; #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 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; }; class DELPHICLASS TJATScanLib; #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() : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JATScanLibClass, _di_JATScanLib> (){} inline __fastcall virtual ~TJATScanLib(); }; #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; }; class DELPHICLASS TJATScanLib_OnResponseListener; #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 { }; class DELPHICLASS TJATScanLib_TagSequenceTask; #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 { }; class DELPHICLASS TJVoid; #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() : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JVoidClass, _di_JVoid> (){} __fastcall virtual ~TJVoid(void){} }; #pragma pack(pop) extern DELPHI_PACKAGE void __fastcall RegisterTypes(); } } } #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 = scan->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 functions in the wrong way?