AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung Delphi Android: .SO erstellen und benutzen
Thema durchsuchen
Ansicht
Themen-Optionen

Android: .SO erstellen und benutzen

Ein Thema von TurboMagic · begonnen am 20. Okt 2023 · letzter Beitrag vom 20. Okt 2023
Antwort Antwort
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.960 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
Benutzerbild von paule32.jk
paule32.jk

Registriert seit: 24. Sep 2022
Ort: Planet Erde
356 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Android: .SO erstellen und benutzen

  Alt 20. Okt 2023, 14:50
Hallo,

LoadLibrary, und WM_(Nachrichten) sind Windows spezifiesch und können nicht in ein Android Project verwendet werden.
Du must Funktionen und Konstanten verwenden, die für Android unterstützt werden
Frag doch einfach
Alles was nicht programmiert werden kann, wird gelötet
  Mit Zitat antworten Zitat
TurboMagic

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

AW: Android: .SO erstellen und benutzen

  Alt 20. Okt 2023, 15:01
Hallo,

deine Antwort mit LoadLibrary ist leider falsch!
Wenn du dir mal System.SysUtils.pas anschaust, wirst du sehen, dass es dort
sowohl ein LoadLibrary für Posix Plattformen gibt!

Das ruft intern dlopen auf!

Und von Windows Botschaftsn hab' ich gar nix geschrieben (ja, war von dir nur ein Beispiel).

Grüße
TurboMagic
  Mit Zitat antworten Zitat
TurboMagic

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

AW: Android: .SO erstellen und benutzen

  Alt 20. Okt 2023, 15:04
Eine neue Erkenntnis (diesmal von D11.3):
Gebe ich mit TPath.GetLibraryPath in einen String aus:

s := TPath.Combine(TPath.GetLibraryPath, 'libSO_Test.so');

Erhalte ich das:
'/data/app/~~td-k7J_qLsGigGgnn9hKrw==/com.embarcadero.SOTestGUI-mFk3eeCSAweRM71VBK_lvw==/lib/arm/libSO_Test.so'

Ich weiß aber nicht ob das korrekt ist und es sieht auch nicht unbeding so aus als würde es zum Remote Pfad
library\lib\armeabi-v7a\ passen...

Wie müsste ich den Remote Pfad ändern?
Einfach in lib/arm/ ist wohl nicht richtig, da ich dann später beim Hinzufügen der 64 Bit .SO ein Problem bekomme...

Grüße
TurboMagic
  Mit Zitat antworten Zitat
Benutzerbild von paule32.jk
paule32.jk

Registriert seit: 24. Sep 2022
Ort: Planet Erde
356 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Android: .SO erstellen und benutzen

  Alt 20. Okt 2023, 15:31
mein altes SAMSUNG Android Galaxy hat die Möglichkeit, die Verzeichnis-Struktur anzeigen
zu lassen.
Frag doch einfach
Alles was nicht programmiert werden kann, wird gelötet
  Mit Zitat antworten Zitat
TurboMagic

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

AW: Android: .SO erstellen und benutzen

  Alt 20. Okt 2023, 15:37
Hallo,

danke für den Tipp.
Leider war ich da auch schon
Nur ist das bei den neueren Geräte meist schreibgeschützt und nicht mal die
Shell (adb shell) kann da überall rein bzw. zeigt Unterordner an.

Aber: glücklicherweise gibt's ja System.SysUtils.FileExists und das sagt, dass
es die betreffende .SO an dem Pfad wirklich gibt.

Tja, nur warum crasht das dann beim LoadLibrary?

Grüße
TurboMagic
  Mit Zitat antworten Zitat
Benutzerbild von paule32.jk
paule32.jk

Registriert seit: 24. Sep 2022
Ort: Planet Erde
356 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Android: .SO erstellen und benutzen

  Alt 20. Okt 2023, 16:58
könnte an die Rechte liegen - oder das falsche binär Format.
Mit den GNU C/C++ kannst Du für beliebige Systeme .EXE, .DLL, .SO schreiben.
Allerdings hat jede Architektur und Chip ein Eigenes Format.

z.B. ist es ein Unterschied, wenn man versucht ein 64 Bit Image auf einer 32 Bit Umgebung zu starten - das geht in der Regel nicht.
Anders als auf einen 64 Bit System, dort können 32 Images gestartet werden.

Dann liegst auch an den Endian / BigEndian.

Oder Du hast Funktionen, die es in dem Image nicht gibt.

Unter Windows in der MSYS2 Shell gibt es wie unter Linux ein Tool namens "ldd" - nicht an den "ld" Linker denken !

LDD prüft, welche Bibliotheken verwendet werden, und zeigt deren "einkompilierten" Pfade an.
Wenn der Pfad nicht existiert, dann wird die Lade-Adresse 0 sein, und führt daher zu einen Lade-Fehler.
Frag doch einfach
Alles was nicht programmiert werden kann, wird gelötet
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#8

AW: Android: .SO erstellen und benutzen

  Alt 20. Okt 2023, 17:13
Anders als auf einen 64 Bit System, dort können 32 Images gestartet werden.
jaaa-nein

So wie im 64 Bit-Windows das 16 Bit-Subsystem entfernt wurde, weswegen man dort keine 16 Bit-DOS-Programme (*.com) mehr starten kann,
kann man auch das 32 Bit SubSystem entfernen. (keine 32 Bit-DLLs und Programme des Windows installieren)
-> dann könnte man zwar in der CPU noch 32 Bit-Code ausführen, aber wenn die 32 Bit-WinAPI fehlt, läuft dennoch fast nichts.

Auch muß man in eine 64 Bit-CPU keine 32 Bit-Instruktionen einbauen (oder das OS verietet das Umschalten),
womit dann garnichts mehr mit 32 Bit ginge.


PS: Das Gegenteil davon macht Wine ... es stellt quasi einen Großteil der Win32-API bereit (vorwiegend als Umleitung auf die Linux-API/Funktionen), wordurch Windows-Programme dort laufen.
$2B or not $2B

Geändert von himitsu (20. Okt 2023 um 17:16 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz