Einzelnen Beitrag anzeigen

TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.942 Beiträge
 
Delphi 12 Athens
 
#1

Android: .SO erstellen und benutzen

  Alt 20. Okt 2023, 13:41
Hallo,

ich versuche gerade eine .SO für Android mit Delphi zu erstellen (10.4.2 oder neuer)
und in einem Testprogramm zu benutzen.

Dazu hab' ich ein Library Projekt erstellt mit einer flachen function drin.
Die hat 2 Integer Parameter und einen Integer Rückgabewert (addiert das einfach nur).

Beim Compilieren wird auch eine .SO Datei erzeugt.
So wie es aussieht kann ich die jedoch nicht statisch einbinden (anders als eine DLL),
weil da der Linker meckert. Also versuche ich das gerade mittels LoadLibrary einzubinden
und ich habe die .SO auch im Deplyoment Manager schon hinzugefügt. Remote-Pfad ist
library\lib\armeabi-v7a\ da ich das bisher mal noch kit 32 Bit zum Testen mache. Funktion
ist cdecl von der Aufruf Konvention.

Nur: zur Laufzeit stürzt die App beim Aufruf einfach ab. Ich prüfe aber den Rückgabewert
von GetProcAddress auf Nil, das kann es also nicht sein.

Logcat hab' ich noch nicht aufgezeichnet, da suche ich noch einen passenden Viewer für, da
ja im Android SDK inzwischen keiner mehr drin ist, ich aber nicht ein komplettes Android
Studio nu für den Viewer installieren möchte...

Code zum Aufruf:

Delphi-Quellcode:
unit GUIMain;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Edit, FMX.Controls.Presentation;

type
  TDoAdd = function(a, b: Integer): Integer; cdecl;

  Tf_Main = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    tf_Summand1: TEdit;
    Label3: TLabel;
    l_Result: TLabel;
    tf_Summand2: TEdit;
    b_Calc: TButton;
    procedure b_CalcClick(Sender: TObject);
  private
    FDoAdd : TDoAdd;
  public
  end;

var
  f_Main: Tf_Main;

implementation

uses
  System.IOUtils;

{$R *.fmx}

{$IFDEF WIN32}
function DoAdd(a, b: Integer): Integer; cdecl; external 'SO_Test.dll';
{$ELSE}
//function DoAdd(a, b: Integer): Integer; cdecl; external 'libSO_Test.so';
{$ENDIF}

procedure Tf_Main.b_CalcClick(Sender: TObject);
var
  Handle : HMODULE;
begin
  Handle := LoadLibrary(PChar(TPath.Combine(TPath.GetLibraryPath,
                              'libSO_Test.so')));

  if (Handle <> 0) then
  begin
    try
      FDoAdd := GetProcAddress(Handle, PChar('DoAdd'));

      if (@FDoAdd = nil) then
        l_Result.Text := 'Failure loading proc'
      else
      begin
        l_Result.Text := FDoAdd(tf_Summand1.Text.ToInteger,
                                tf_Summand2.Text.ToInteger).ToString;
        FDoAdd := nil;
      end;
    finally
      FreeLibrary(Handle);
    end;
  end
  else
    l_Result.Text := 'SO handle is invalid'
end;

end.
Hier der relevante Logcat Auszug:

Code:
10-20 13:36:28.234 31445 31445 W adero.SOTestGU: Accessing hidden method Landroid/view/MotionEvent;-><init>()V (greylist-max-o, JNI, denied): com.embarcadero.SOTestGUI
10-20 13:36:28.451  1513  2333 W InputDispatcher: channel 'a66b6a3 PopupWindow:efeb1b3 (server)' ~ Consumer closed input channel or an error occurred. events=0x9: system_server
10-20 13:36:28.451  1513  2333 E InputDispatcher: channel 'a66b6a3 PopupWindow:efeb1b3 (server)' ~ Channel is unrecoverably broken and will be disposed!: system_server
10-20 13:36:28.452  1513  2333 W InputDispatcher: channel '1179c6e com.embarcadero.SOTestGUI/com.embarcadero.firemonkey.FMXNativeActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x9: system_server
10-20 13:36:28.452  1513  2333 E InputDispatcher: channel '1179c6e com.embarcadero.SOTestGUI/com.embarcadero.firemonkey.FMXNativeActivity (server)' ~ Channel is unrecoverably broken and will be disposed!: system_server
10-20 13:36:28.463  1513  3607 W InputDispatcher: Attempted to unregister already unregistered input channel 'a66b6a3 PopupWindow:efeb1b3 (server)': system_server
10-20 13:36:28.464  1513  6252 I am_proc_died: [0,31445,com.embarcadero.SOTestGUI,0,2]: system_server
10-20 13:36:28.466   700   700 I Zygote : Process 31445 exited cleanly (231)
10-20 13:36:28.472  1513  2359 W InputDispatcher: Attempted to unregister already unregistered input channel '1179c6e com.embarcadero.SOTestGUI/com.embarcadero.firemonkey.FMXNativeActivity (server)': system_server
10-20 13:36:28.486  1513  6252 I am_uid_stopped: 10310: system_server
10-20 13:36:28.488  1513  6252 I wm_finish_activity: [0,18028204,39,com.embarcadero.SOTestGUI/com.embarcadero.firemonkey.FMXNativeActivity,proc died without state saved]: system_server
10-20 13:36:28.492  1513  6252 I wm_task_removed: [39,removeChild: last r=ActivityRecord{11316ac u0 com.embarcadero.SOTestGUI/com.embarcadero.firemonkey.FMXNativeActivity t-1 f}} in t=Task{f2191ae #39 visible=false type=standard mode=fullscreen translucent=true A=10310:com.embarcadero.SOTestGUI U=0 StackId=39 sz=0}]: system_server
10-20 13:36:28.492  1513  6252 I wm_task_removed: [39,removeTask]: system_server
10-20 13:36:28.492  1513  6252 I wm_task_removed: [39,removeTask]: system_server
10-20 13:36:28.492  1513  6252 I wm_stack_removed: 39: system_server
10-20 13:36:28.496  1513  6252 I wm_set_resumed_activity: [0,com.google.android.packageinstaller/com.android.packageinstaller.DeleteStagedFileOnResult,resumeTopActivityInnerLocked]: system_server
10-20 13:36:28.497  1513  6252 D hmdEnterprise: <isUninstallPackage> blockUninstallpackage =false: system_server
10-20 13:36:28.500  1513  1775 I libprocessgroup: Successfully killed process cgroup uid 10310 pid 31445 in 36ms: system_server
Wer hat noch eine Idee?
Die nächsten Versuche werde ich mit StdCall Aufrufkonvention und von 11.3 aus durchführen.
Evtl. noch die .SO in einen anderen Pfad bereitstellen lassen? .\internal\assets vielleicht?
  Mit Zitat antworten Zitat