Android JNI bridge Toast C++ 不工作 - 如何修复?
Android JNI bridge Toast C++ not working - How to fix it?
我正在尝试解决我的 hpp 设备的一个小问题。
我在互联网上找到了一些示例,展示了如何使用 Android JNI 桥在屏幕上吐司信息,但它只是在 pascal (delphi) 中,所以我决定使用相同的 pas 文件,但它是一个用于转换的 hpp 文件。
直到现在我明白了:
#ifndef Android_Jni_ToastHPP
#define Android_Jni_ToastHPP
#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 <FMX.Helpers.Android.hpp> // Pascal unit
#include <Androidapi.JNIBridge.hpp> // Pascal unit
#include <Androidapi.JNI.JavaTypes.hpp> // Pascal unit
#include <Androidapi.JNI.GraphicsContentViewText.hpp> // Pascal unit
#include <Androidapi.JNI.Util.hpp> // Pascal unit
#include <Androidapi.JNI.App.hpp> // Pascal unit
#include <FMX.Surfaces.hpp> // Pascal unit
//-- user supplied -----------------------------------------------------------
namespace Android
{
namespace Jni
{
namespace Toast
{
//-- type declarations -------------------------------------------------------
extern DELPHI_PACKAGE Androidapi::Jni::Toast __fastcall Toast(const System::UnicodeString Msg, TToastLength duration);
#pragma pack(pop)
//-- type declarations -------------------------------------------------------
//-- var, const, procedure ---------------------------------------------------
} /* namespace Android */
} /* namespace JNI */
} /* namespace Toast */
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROID_JNI_TOAST)
using namespace Android::Jni::Toast;
#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.
//-- end unit ----------------------------------------------------------------
#endif // Androidapi_Jni_ToastHPP
如果你想要帕斯卡单位,就在这里:
unit Android.JNI.Toast;
interface
{$IFDEF ANDROID}
uses
Androidapi.JNIBridge,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.GraphicsContentViewText;
{$ENDIF}
{$IFDEF ANDROID}
type
TToastLength = (LongToast, ShortToast);
JToast = interface;
JToastClass = interface(JObjectClass)
['{69E2D233-B9D3-4F3E-B882-474C8E1D50E9}']
{ Property methods }
function _GetLENGTH_LONG: Integer; cdecl;
function _GetLENGTH_SHORT: Integer; cdecl;
{ Methods }
function init(context: JContext): JToast; cdecl; overload;
function makeText(context: JContext; text: JCharSequence; duration: Integer)
: JToast; cdecl;
{ Properties }
property LENGTH_LONG: Integer read _GetLENGTH_LONG;
property LENGTH_SHORT: Integer read _GetLENGTH_SHORT;
end;
[JavaSignature('android/widget/Toast')]
JToast = interface(JObject)
['{FD81CC32-BFBC-4838-8893-9DD01DE47B00}']
{ Methods }
procedure cancel; cdecl;
function getDuration: Integer; cdecl;
function getGravity: Integer; cdecl;
function getHorizontalMargin: Single; cdecl;
function getVerticalMargin: Single; cdecl;
function getView: JView; cdecl;
function getXOffset: Integer; cdecl;
function getYOffset: Integer; cdecl;
procedure setDuration(value: Integer); cdecl;
procedure setGravity(gravity, xOffset, yOffset: Integer); cdecl;
procedure setMargin(horizontalMargin, verticalMargin: Single); cdecl;
procedure setText(s: JCharSequence); cdecl;
procedure setView(view: JView); cdecl;
procedure show; cdecl;
end;
TJToast = class(TJavaGenericImport<JToastClass, JToast>)
end;
procedure Toast(const Msg: string; duration: TToastLength = ShortToast);
{$ENDIF}
implementation
{$IFDEF ANDROID}
uses
FMX.Helpers.Android, Androidapi.Helpers;
procedure Toast(const Msg: string; duration: TToastLength);
var
ToastLength: Integer;
begin
if duration = ShortToast then
ToastLength := TJToast.JavaClass.LENGTH_SHORT
else
ToastLength := TJToast.JavaClass.LENGTH_LONG;
CallInUiThread(
procedure
begin
TJToast.JavaClass.makeText(SharedActivityContext, StrToJCharSequence(Msg),
ToastLength).show
end);
end;
{$ENDIF}
end.
但是在使用这个源进行编译时出现错误...
我做什么骗局?
PS.: 我到达那个状态只是将 AppMetthod 源与我正在制作的进行比较...
日志:
Checking project dependencies...
Compiling WebBrowser.cbproj (Debug, Android)
bccaarm command line for "uMain.cpp"
c:\program files (x86)\embarcadero\studio.0\bin\bccaarm.exe -cc1 -D _DEBUG -isysroot
C:\Users\Public\Documents\Embarcadero\Studio.0\PlatformSDKs\android-ndk-r9c\platforms\android-14\arch-arm -idirafter =\usr\include -idirafter
C:\Users\Public\Documents\Embarcadero\Studio.0\PlatformSDKs\android-ndk-r9c\sources\cxx-stl\gnu-libstdc++.8\include -idirafter
C:\Users\Public\Documents\Embarcadero\Studio.0\PlatformSDKs\android-ndk-r9c\sources\cxx-stl\gnu-libstdc++.8\libs\armeabi-v7a\include -idirafter
C:\Users\Public\Documents\Embarcadero\Studio.0\PlatformSDKs\android-ndk-r9c\sources\android\native_app_glue -I
"C:\Users\Public\Documents\Embarcadero\Studio.0\Samples\CPP\Mobile Snippets\WebBrowser" -isystem "c:\program files
(x86)\embarcadero\studio.0\include" -isystem "c:\program files (x86)\embarcadero\studio.0\include\android\rtl" -isystem "c:\program files
(x86)\embarcadero\studio.0\include\android\fmx" -isystem "c:\program files (x86)\embarcadero\studio.0\include\android\crtl" -g
-fno-limit-debug-info -fborland-extensions -fborland-auto-refcount -nobuiltininc -nostdsysteminc -triple thumbv7-none-linux-androideabi -emit-obj
-mconstructor-aliases -pic-level 2 -target-abi aapcs-linux -nostdinc++ -fdeprecated-macro -fexceptions -fcxx-exceptions -munwind-tables
-mstackrealign -fno-spell-checking -fno-use-cxa-atexit -main-file-name uMain.cpp -x c++ -std=c++11 -O0 -tU -o .\Android\Debug\uMain.o
-dependency-file .\Android\Debug\uMain.d -MT .\Android\Debug\uMain.o uMain.cpp
[bccaarm Error] Android.JNI.Toast.hpp(36): expected a class or namespace
[bccaarm Error] Android.JNI.Toast.hpp(36): reference to 'Android' is ambiguous
Android.JNI.Toast.hpp(28): candidate found by name lookup is 'Android'
FMX.Helpers.Android.hpp(28): candidate found by name lookup is 'Fmx::Helpers::Android'
[bccaarm Error] Android.JNI.Toast.hpp(36): expected unqualified-id
[bccaarm Error] Android.JNI.Toast.hpp(47): expected a class or namespace
[bccaarm Error] Android.JNI.Toast.hpp(47): reference to 'Android' is ambiguous
Android.JNI.Toast.hpp(28): candidate found by name lookup is 'Android'
FMX.Helpers.Android.hpp(28): candidate found by name lookup is 'Fmx::Helpers::Android'
[bccaarm Error] Android.JNI.Toast.hpp(47): expected namespace name
[bccaarm Error] Android.JNI.Toast.hpp(50): expected a class or namespace
[bccaarm Error] Android.JNI.Toast.hpp(50): reference to 'Android' is ambiguous
Android.JNI.Toast.hpp(28): candidate found by name lookup is 'Android'
FMX.Helpers.Android.hpp(28): candidate found by name lookup is 'Fmx::Helpers::Android'
[bccaarm Error] Android.JNI.Toast.hpp(50): expected namespace name
[bccaarm Error] Android.JNI.Toast.hpp(53): reference to 'Android' is ambiguous
Android.JNI.Toast.hpp(28): candidate found by name lookup is 'Android'
FMX.Helpers.Android.hpp(28): candidate found by name lookup is 'Fmx::Helpers::Android'
[bccaarm Error] uMain.cpp(32): use of undeclared identifier 'Toast'
Failed
Elapsed time: 00:00:05.8
编辑:
新日志文件:
[bccaarm Error] Androidapi.JNI.Toast.hpp(36): no type named 'Toast' in namespace 'Androidapi::Jni'
[bccaarm Error] Androidapi.JNI.Toast.hpp(36): expected unqualified-id
[bccaarm Error] uMain.cpp(32): unexpected namespace name 'Toast': expected expression
Failed
从现在开始,非常感谢。
.hpp 文件格式不正确。
在 .pas
文件的 interface
部分定义的 public 类型中的 None 在 .hpp
文件中定义。特别是缺少 TToastLength
枚举。 Toast()
在 .pas 文件中被声明为 procedure
,因此没有 return 值,但它在 .hpp 文件中有一个(错误的)return 值。
您(或其他人)是否手动创建了 .hpp 文件?我怀疑是这种情况,原因有两个:
初始#ifndef
/#define
中定义的Android_JNI_ToastHPP
与对应的#endif
中的Fmx_Helpers_AndroidHPP
不匹配。
Delphi 编译器总是通过大写第一个字母并小写其余字母来为 Pascal 单元名称命名 C++ 命名空间,但是这个 .hpp 文件有一个全大写 JNI
命名空间。
Delphi 编译器不会犯这些错误。
话虽如此,为了与 Embarcadero 的其他 JNI 单元保持一致(并匹配this article)。这也应该有助于减轻 reference to 'Android' is ambiguous
错误。
我强烈建议您更正 .pas 文件,运行 通过 Delphi 编译器一次生成正确的 .hpp 文件,然后在您的 C++ 代码中按原样使用它。
Androidapi.JNI.Toast.pas:
unit Androidapi.JNI.Toast;
interface
{$IFDEF ANDROID}
uses
Androidapi.JNIBridge,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.GraphicsContentViewText;
type
TToastLength = (LongToast, ShortToast);
JToast = interface;
JToastClass = interface(JObjectClass)
['{69E2D233-B9D3-4F3E-B882-474C8E1D50E9}']
{ Property methods }
function _GetLENGTH_LONG: Integer; cdecl;
function _GetLENGTH_SHORT: Integer; cdecl;
{ Methods }
function init(context: JContext): JToast; cdecl; overload;
function makeText(context: JContext; text: JCharSequence; duration: Integer)
: JToast; cdecl;
{ Properties }
property LENGTH_LONG: Integer read _GetLENGTH_LONG;
property LENGTH_SHORT: Integer read _GetLENGTH_SHORT;
end;
[JavaSignature('android/widget/Toast')]
JToast = interface(JObject)
['{FD81CC32-BFBC-4838-8893-9DD01DE47B00}']
{ Methods }
procedure cancel; cdecl;
function getDuration: Integer; cdecl;
function getGravity: Integer; cdecl;
function getHorizontalMargin: Single; cdecl;
function getVerticalMargin: Single; cdecl;
function getView: JView; cdecl;
function getXOffset: Integer; cdecl;
function getYOffset: Integer; cdecl;
procedure setDuration(value: Integer); cdecl;
procedure setGravity(gravity, xOffset, yOffset: Integer); cdecl;
procedure setMargin(horizontalMargin, verticalMargin: Single); cdecl;
procedure setText(s: JCharSequence); cdecl;
procedure setView(view: JView); cdecl;
procedure show; cdecl;
end;
TJToast = class(TJavaGenericImport<JToastClass, JToast>)
end;
procedure Toast(const Msg: string; duration: TToastLength = ShortToast);
{$ENDIF}
implementation
{$IFDEF ANDROID}
uses
FMX.Helpers.Android, Androidapi.Helpers;
procedure Toast(const Msg: string; duration: TToastLength);
var
ToastLength: Integer;
begin
if duration = ShortToast then
ToastLength := TJToast.JavaClass.LENGTH_SHORT
else
ToastLength := TJToast.JavaClass.LENGTH_LONG;
CallInUiThread(
procedure
begin
TJToast.JavaClass.makeText(SharedActivityContext, StrToJCharSequence(Msg),
ToastLength).show
end);
end;
{$ENDIF}
end.
Androidapi.JNI.Toast.hpp:
// CodeGear C++Builder
// Copyright (c) 1995, 2014 by Embarcadero Technologies, Inc.
// All rights reserved
// (DO NOT EDIT: machine generated header) 'Androidapi.JNI.Toast.pas' rev: 28.00 (Android)
#ifndef Androidapi_Jni_ToastHPP
#define Androidapi_Jni_ToastHPP
#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 <System.hpp> // Pascal unit
#include <SysInit.hpp> // Pascal unit
#include <Androidapi.JNIBridge.hpp> // Pascal unit
#include <Androidapi.JNI.JavaTypes.hpp> // Pascal unit
#include <Androidapi.JNI.GraphicsContentViewText.hpp> // Pascal unit
#include <System.Rtti.hpp> // Pascal unit
//-- user supplied -----------------------------------------------------------
namespace Androidapi
{
namespace Jni
{
namespace Toast
{
//-- type declarations -------------------------------------------------------
enum DECLSPEC_DENUM TToastLength : unsigned char { LongToast, ShortToast };
__interface JToastClass;
typedef System::DelphiInterface<JToastClass> _di_JToastClass;
__interface JToast;
typedef System::DelphiInterface<JToast> _di_JToast;
__interface INTERFACE_UUID("{69E2D233-B9D3-4F3E-B882-474C8E1D50E9}") JToastClass : public Androidapi::Jni::Javatypes::JObjectClass
{
public:
virtual int __cdecl _GetLENGTH_LONG(void) = 0 ;
virtual int __cdecl _GetLENGTH_SHORT(void) = 0 ;
HIDESBASE virtual _di_JToast __cdecl init(Androidapi::Jni::Graphicscontentviewtext::_di_JContext context) = 0 /* overload */;
virtual _di_JToast __cdecl makeText(Androidapi::Jni::Graphicscontentviewtext::_di_JContext context, Androidapi::Jni::Javatypes::_di_JCharSequence text, int duration) = 0 ;
__property int LENGTH_LONG = {read=_GetLENGTH_LONG};
__property int LENGTH_SHORT = {read=_GetLENGTH_SHORT};
};
__interface INTERFACE_UUID("{FD81CC32-BFBC-4838-8893-9DD01DE47B00}") JToast : public Androidapi::Jni::Javatypes::JObject
{
public:
virtual void __cdecl cancel(void) = 0 ;
virtual int __cdecl getDuration(void) = 0 ;
virtual int __cdecl getGravity(void) = 0 ;
virtual float __cdecl getHorizontalMargin(void) = 0 ;
virtual float __cdecl getVerticalMargin(void) = 0 ;
virtual Androidapi::Jni::Graphicscontentviewtext::_di_JView __cdecl getView(void) = 0 ;
virtual int __cdecl getXOffset(void) = 0 ;
virtual int __cdecl getYOffset(void) = 0 ;
virtual void __cdecl setDuration(int value) = 0 ;
virtual void __cdecl setGravity(int gravity, int xOffset, int yOffset) = 0 ;
virtual void __cdecl setMargin(float horizontalMargin, float verticalMargin) = 0 ;
virtual void __cdecl setText(Androidapi::Jni::Javatypes::_di_JCharSequence s) = 0 ;
virtual void __cdecl setView(Androidapi::Jni::Graphicscontentviewtext::_di_JView view) = 0 ;
virtual void __cdecl show(void) = 0 ;
};
class DELPHICLASS TJToast;
#pragma pack(push,4)
class PASCALIMPLEMENTATION TJToast : public Androidapi::Jnibridge::TJavaGenericImport__2<_di_JToastClass,_di_JToast>
{
typedef Androidapi::Jnibridge::TJavaGenericImport__2<_di_JToastClass,_di_JToast> inherited;
public:
/* TJavaImport.Create */ inline __fastcall TJToast(void * ID, void * ClsID, Androidapi::Jnibridge::TJavaVTable* VTable) : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JToastClass,_di_JToast> (ID, ClsID, VTable) { }
/* TJavaImport.Destroy */ inline __fastcall virtual ~TJToast(void) { }
};
#pragma pack(pop)
//-- var, const, procedure ---------------------------------------------------
extern DELPHI_PACKAGE void __fastcall Toast(const System::UnicodeString Msg, TToastLength duration = (TToastLength)(0x1));
} /* namespace Toast */
} /* namespace Jni */
} /* namespace Androidapi */
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROIDAPI_JNI_TOAST)
using namespace Androidapi::Jni::Toast;
#endif
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROIDAPI_JNI)
using namespace Androidapi::Jni;
#endif
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROIDAPI)
using namespace Androidapi;
#endif
#pragma pack(pop)
#pragma option pop
#pragma delphiheader end.
//-- end unit ----------------------------------------------------------------
#endif // Androidapi_Jni_ToastHPP
我正在尝试解决我的 hpp 设备的一个小问题。 我在互联网上找到了一些示例,展示了如何使用 Android JNI 桥在屏幕上吐司信息,但它只是在 pascal (delphi) 中,所以我决定使用相同的 pas 文件,但它是一个用于转换的 hpp 文件。 直到现在我明白了:
#ifndef Android_Jni_ToastHPP
#define Android_Jni_ToastHPP
#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 <FMX.Helpers.Android.hpp> // Pascal unit
#include <Androidapi.JNIBridge.hpp> // Pascal unit
#include <Androidapi.JNI.JavaTypes.hpp> // Pascal unit
#include <Androidapi.JNI.GraphicsContentViewText.hpp> // Pascal unit
#include <Androidapi.JNI.Util.hpp> // Pascal unit
#include <Androidapi.JNI.App.hpp> // Pascal unit
#include <FMX.Surfaces.hpp> // Pascal unit
//-- user supplied -----------------------------------------------------------
namespace Android
{
namespace Jni
{
namespace Toast
{
//-- type declarations -------------------------------------------------------
extern DELPHI_PACKAGE Androidapi::Jni::Toast __fastcall Toast(const System::UnicodeString Msg, TToastLength duration);
#pragma pack(pop)
//-- type declarations -------------------------------------------------------
//-- var, const, procedure ---------------------------------------------------
} /* namespace Android */
} /* namespace JNI */
} /* namespace Toast */
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROID_JNI_TOAST)
using namespace Android::Jni::Toast;
#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.
//-- end unit ----------------------------------------------------------------
#endif // Androidapi_Jni_ToastHPP
如果你想要帕斯卡单位,就在这里:
unit Android.JNI.Toast;
interface
{$IFDEF ANDROID}
uses
Androidapi.JNIBridge,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.GraphicsContentViewText;
{$ENDIF}
{$IFDEF ANDROID}
type
TToastLength = (LongToast, ShortToast);
JToast = interface;
JToastClass = interface(JObjectClass)
['{69E2D233-B9D3-4F3E-B882-474C8E1D50E9}']
{ Property methods }
function _GetLENGTH_LONG: Integer; cdecl;
function _GetLENGTH_SHORT: Integer; cdecl;
{ Methods }
function init(context: JContext): JToast; cdecl; overload;
function makeText(context: JContext; text: JCharSequence; duration: Integer)
: JToast; cdecl;
{ Properties }
property LENGTH_LONG: Integer read _GetLENGTH_LONG;
property LENGTH_SHORT: Integer read _GetLENGTH_SHORT;
end;
[JavaSignature('android/widget/Toast')]
JToast = interface(JObject)
['{FD81CC32-BFBC-4838-8893-9DD01DE47B00}']
{ Methods }
procedure cancel; cdecl;
function getDuration: Integer; cdecl;
function getGravity: Integer; cdecl;
function getHorizontalMargin: Single; cdecl;
function getVerticalMargin: Single; cdecl;
function getView: JView; cdecl;
function getXOffset: Integer; cdecl;
function getYOffset: Integer; cdecl;
procedure setDuration(value: Integer); cdecl;
procedure setGravity(gravity, xOffset, yOffset: Integer); cdecl;
procedure setMargin(horizontalMargin, verticalMargin: Single); cdecl;
procedure setText(s: JCharSequence); cdecl;
procedure setView(view: JView); cdecl;
procedure show; cdecl;
end;
TJToast = class(TJavaGenericImport<JToastClass, JToast>)
end;
procedure Toast(const Msg: string; duration: TToastLength = ShortToast);
{$ENDIF}
implementation
{$IFDEF ANDROID}
uses
FMX.Helpers.Android, Androidapi.Helpers;
procedure Toast(const Msg: string; duration: TToastLength);
var
ToastLength: Integer;
begin
if duration = ShortToast then
ToastLength := TJToast.JavaClass.LENGTH_SHORT
else
ToastLength := TJToast.JavaClass.LENGTH_LONG;
CallInUiThread(
procedure
begin
TJToast.JavaClass.makeText(SharedActivityContext, StrToJCharSequence(Msg),
ToastLength).show
end);
end;
{$ENDIF}
end.
但是在使用这个源进行编译时出现错误... 我做什么骗局?
PS.: 我到达那个状态只是将 AppMetthod 源与我正在制作的进行比较...
日志:
Checking project dependencies...
Compiling WebBrowser.cbproj (Debug, Android)
bccaarm command line for "uMain.cpp"
c:\program files (x86)\embarcadero\studio.0\bin\bccaarm.exe -cc1 -D _DEBUG -isysroot
C:\Users\Public\Documents\Embarcadero\Studio.0\PlatformSDKs\android-ndk-r9c\platforms\android-14\arch-arm -idirafter =\usr\include -idirafter
C:\Users\Public\Documents\Embarcadero\Studio.0\PlatformSDKs\android-ndk-r9c\sources\cxx-stl\gnu-libstdc++.8\include -idirafter
C:\Users\Public\Documents\Embarcadero\Studio.0\PlatformSDKs\android-ndk-r9c\sources\cxx-stl\gnu-libstdc++.8\libs\armeabi-v7a\include -idirafter
C:\Users\Public\Documents\Embarcadero\Studio.0\PlatformSDKs\android-ndk-r9c\sources\android\native_app_glue -I
"C:\Users\Public\Documents\Embarcadero\Studio.0\Samples\CPP\Mobile Snippets\WebBrowser" -isystem "c:\program files
(x86)\embarcadero\studio.0\include" -isystem "c:\program files (x86)\embarcadero\studio.0\include\android\rtl" -isystem "c:\program files
(x86)\embarcadero\studio.0\include\android\fmx" -isystem "c:\program files (x86)\embarcadero\studio.0\include\android\crtl" -g
-fno-limit-debug-info -fborland-extensions -fborland-auto-refcount -nobuiltininc -nostdsysteminc -triple thumbv7-none-linux-androideabi -emit-obj
-mconstructor-aliases -pic-level 2 -target-abi aapcs-linux -nostdinc++ -fdeprecated-macro -fexceptions -fcxx-exceptions -munwind-tables
-mstackrealign -fno-spell-checking -fno-use-cxa-atexit -main-file-name uMain.cpp -x c++ -std=c++11 -O0 -tU -o .\Android\Debug\uMain.o
-dependency-file .\Android\Debug\uMain.d -MT .\Android\Debug\uMain.o uMain.cpp
[bccaarm Error] Android.JNI.Toast.hpp(36): expected a class or namespace
[bccaarm Error] Android.JNI.Toast.hpp(36): reference to 'Android' is ambiguous
Android.JNI.Toast.hpp(28): candidate found by name lookup is 'Android'
FMX.Helpers.Android.hpp(28): candidate found by name lookup is 'Fmx::Helpers::Android'
[bccaarm Error] Android.JNI.Toast.hpp(36): expected unqualified-id
[bccaarm Error] Android.JNI.Toast.hpp(47): expected a class or namespace
[bccaarm Error] Android.JNI.Toast.hpp(47): reference to 'Android' is ambiguous
Android.JNI.Toast.hpp(28): candidate found by name lookup is 'Android'
FMX.Helpers.Android.hpp(28): candidate found by name lookup is 'Fmx::Helpers::Android'
[bccaarm Error] Android.JNI.Toast.hpp(47): expected namespace name
[bccaarm Error] Android.JNI.Toast.hpp(50): expected a class or namespace
[bccaarm Error] Android.JNI.Toast.hpp(50): reference to 'Android' is ambiguous
Android.JNI.Toast.hpp(28): candidate found by name lookup is 'Android'
FMX.Helpers.Android.hpp(28): candidate found by name lookup is 'Fmx::Helpers::Android'
[bccaarm Error] Android.JNI.Toast.hpp(50): expected namespace name
[bccaarm Error] Android.JNI.Toast.hpp(53): reference to 'Android' is ambiguous
Android.JNI.Toast.hpp(28): candidate found by name lookup is 'Android'
FMX.Helpers.Android.hpp(28): candidate found by name lookup is 'Fmx::Helpers::Android'
[bccaarm Error] uMain.cpp(32): use of undeclared identifier 'Toast'
Failed
Elapsed time: 00:00:05.8
编辑:
新日志文件:
[bccaarm Error] Androidapi.JNI.Toast.hpp(36): no type named 'Toast' in namespace 'Androidapi::Jni'
[bccaarm Error] Androidapi.JNI.Toast.hpp(36): expected unqualified-id
[bccaarm Error] uMain.cpp(32): unexpected namespace name 'Toast': expected expression
Failed
从现在开始,非常感谢。
.hpp 文件格式不正确。
在.pas
文件的 interface
部分定义的 public 类型中的 None 在 .hpp
文件中定义。特别是缺少 TToastLength
枚举。 Toast()
在 .pas 文件中被声明为 procedure
,因此没有 return 值,但它在 .hpp 文件中有一个(错误的)return 值。
您(或其他人)是否手动创建了 .hpp 文件?我怀疑是这种情况,原因有两个:
初始
#ifndef
/#define
中定义的Android_JNI_ToastHPP
与对应的#endif
中的Fmx_Helpers_AndroidHPP
不匹配。Delphi 编译器总是通过大写第一个字母并小写其余字母来为 Pascal 单元名称命名 C++ 命名空间,但是这个 .hpp 文件有一个全大写
JNI
命名空间。
Delphi 编译器不会犯这些错误。
话虽如此,为了与 Embarcadero 的其他 JNI 单元保持一致(并匹配this article)。这也应该有助于减轻 reference to 'Android' is ambiguous
错误。
我强烈建议您更正 .pas 文件,运行 通过 Delphi 编译器一次生成正确的 .hpp 文件,然后在您的 C++ 代码中按原样使用它。
Androidapi.JNI.Toast.pas:
unit Androidapi.JNI.Toast;
interface
{$IFDEF ANDROID}
uses
Androidapi.JNIBridge,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.GraphicsContentViewText;
type
TToastLength = (LongToast, ShortToast);
JToast = interface;
JToastClass = interface(JObjectClass)
['{69E2D233-B9D3-4F3E-B882-474C8E1D50E9}']
{ Property methods }
function _GetLENGTH_LONG: Integer; cdecl;
function _GetLENGTH_SHORT: Integer; cdecl;
{ Methods }
function init(context: JContext): JToast; cdecl; overload;
function makeText(context: JContext; text: JCharSequence; duration: Integer)
: JToast; cdecl;
{ Properties }
property LENGTH_LONG: Integer read _GetLENGTH_LONG;
property LENGTH_SHORT: Integer read _GetLENGTH_SHORT;
end;
[JavaSignature('android/widget/Toast')]
JToast = interface(JObject)
['{FD81CC32-BFBC-4838-8893-9DD01DE47B00}']
{ Methods }
procedure cancel; cdecl;
function getDuration: Integer; cdecl;
function getGravity: Integer; cdecl;
function getHorizontalMargin: Single; cdecl;
function getVerticalMargin: Single; cdecl;
function getView: JView; cdecl;
function getXOffset: Integer; cdecl;
function getYOffset: Integer; cdecl;
procedure setDuration(value: Integer); cdecl;
procedure setGravity(gravity, xOffset, yOffset: Integer); cdecl;
procedure setMargin(horizontalMargin, verticalMargin: Single); cdecl;
procedure setText(s: JCharSequence); cdecl;
procedure setView(view: JView); cdecl;
procedure show; cdecl;
end;
TJToast = class(TJavaGenericImport<JToastClass, JToast>)
end;
procedure Toast(const Msg: string; duration: TToastLength = ShortToast);
{$ENDIF}
implementation
{$IFDEF ANDROID}
uses
FMX.Helpers.Android, Androidapi.Helpers;
procedure Toast(const Msg: string; duration: TToastLength);
var
ToastLength: Integer;
begin
if duration = ShortToast then
ToastLength := TJToast.JavaClass.LENGTH_SHORT
else
ToastLength := TJToast.JavaClass.LENGTH_LONG;
CallInUiThread(
procedure
begin
TJToast.JavaClass.makeText(SharedActivityContext, StrToJCharSequence(Msg),
ToastLength).show
end);
end;
{$ENDIF}
end.
Androidapi.JNI.Toast.hpp:
// CodeGear C++Builder
// Copyright (c) 1995, 2014 by Embarcadero Technologies, Inc.
// All rights reserved
// (DO NOT EDIT: machine generated header) 'Androidapi.JNI.Toast.pas' rev: 28.00 (Android)
#ifndef Androidapi_Jni_ToastHPP
#define Androidapi_Jni_ToastHPP
#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 <System.hpp> // Pascal unit
#include <SysInit.hpp> // Pascal unit
#include <Androidapi.JNIBridge.hpp> // Pascal unit
#include <Androidapi.JNI.JavaTypes.hpp> // Pascal unit
#include <Androidapi.JNI.GraphicsContentViewText.hpp> // Pascal unit
#include <System.Rtti.hpp> // Pascal unit
//-- user supplied -----------------------------------------------------------
namespace Androidapi
{
namespace Jni
{
namespace Toast
{
//-- type declarations -------------------------------------------------------
enum DECLSPEC_DENUM TToastLength : unsigned char { LongToast, ShortToast };
__interface JToastClass;
typedef System::DelphiInterface<JToastClass> _di_JToastClass;
__interface JToast;
typedef System::DelphiInterface<JToast> _di_JToast;
__interface INTERFACE_UUID("{69E2D233-B9D3-4F3E-B882-474C8E1D50E9}") JToastClass : public Androidapi::Jni::Javatypes::JObjectClass
{
public:
virtual int __cdecl _GetLENGTH_LONG(void) = 0 ;
virtual int __cdecl _GetLENGTH_SHORT(void) = 0 ;
HIDESBASE virtual _di_JToast __cdecl init(Androidapi::Jni::Graphicscontentviewtext::_di_JContext context) = 0 /* overload */;
virtual _di_JToast __cdecl makeText(Androidapi::Jni::Graphicscontentviewtext::_di_JContext context, Androidapi::Jni::Javatypes::_di_JCharSequence text, int duration) = 0 ;
__property int LENGTH_LONG = {read=_GetLENGTH_LONG};
__property int LENGTH_SHORT = {read=_GetLENGTH_SHORT};
};
__interface INTERFACE_UUID("{FD81CC32-BFBC-4838-8893-9DD01DE47B00}") JToast : public Androidapi::Jni::Javatypes::JObject
{
public:
virtual void __cdecl cancel(void) = 0 ;
virtual int __cdecl getDuration(void) = 0 ;
virtual int __cdecl getGravity(void) = 0 ;
virtual float __cdecl getHorizontalMargin(void) = 0 ;
virtual float __cdecl getVerticalMargin(void) = 0 ;
virtual Androidapi::Jni::Graphicscontentviewtext::_di_JView __cdecl getView(void) = 0 ;
virtual int __cdecl getXOffset(void) = 0 ;
virtual int __cdecl getYOffset(void) = 0 ;
virtual void __cdecl setDuration(int value) = 0 ;
virtual void __cdecl setGravity(int gravity, int xOffset, int yOffset) = 0 ;
virtual void __cdecl setMargin(float horizontalMargin, float verticalMargin) = 0 ;
virtual void __cdecl setText(Androidapi::Jni::Javatypes::_di_JCharSequence s) = 0 ;
virtual void __cdecl setView(Androidapi::Jni::Graphicscontentviewtext::_di_JView view) = 0 ;
virtual void __cdecl show(void) = 0 ;
};
class DELPHICLASS TJToast;
#pragma pack(push,4)
class PASCALIMPLEMENTATION TJToast : public Androidapi::Jnibridge::TJavaGenericImport__2<_di_JToastClass,_di_JToast>
{
typedef Androidapi::Jnibridge::TJavaGenericImport__2<_di_JToastClass,_di_JToast> inherited;
public:
/* TJavaImport.Create */ inline __fastcall TJToast(void * ID, void * ClsID, Androidapi::Jnibridge::TJavaVTable* VTable) : Androidapi::Jnibridge::TJavaGenericImport__2<_di_JToastClass,_di_JToast> (ID, ClsID, VTable) { }
/* TJavaImport.Destroy */ inline __fastcall virtual ~TJToast(void) { }
};
#pragma pack(pop)
//-- var, const, procedure ---------------------------------------------------
extern DELPHI_PACKAGE void __fastcall Toast(const System::UnicodeString Msg, TToastLength duration = (TToastLength)(0x1));
} /* namespace Toast */
} /* namespace Jni */
} /* namespace Androidapi */
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROIDAPI_JNI_TOAST)
using namespace Androidapi::Jni::Toast;
#endif
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROIDAPI_JNI)
using namespace Androidapi::Jni;
#endif
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_ANDROIDAPI)
using namespace Androidapi;
#endif
#pragma pack(pop)
#pragma option pop
#pragma delphiheader end.
//-- end unit ----------------------------------------------------------------
#endif // Androidapi_Jni_ToastHPP