Трудности с вызовом функции Android NDK напрямую из Delphi

Можно вызвать C-функцию Android из Delphi черезJNI и NDK, Для реализации этого достаточно много работы, и было предложено напрямую вызывать NDK-функции. Для этого я создал небольшой файл примера, чтобы объявить внешнюю функцию C в соответствии с тем, что я нашел в исходном коде Delphi. Более конкретно в.\source\rtl\android

Я создал очень маленькую тестовую программу для проверки функциональности вызова C-функции непосредственно из Delphi. Весь исходный код выНиже я найду, это то, что я сейчас тестирую.

  unit DLL_external;

  interface

  const
     MIDI_Lib = '/usr/lib/libmiditest.so';
     test_fun = 'test_1';

  function test_1 (n: Integer): Integer; cdecl;
    external MIDI_Lib name test_fun;

  implementation

  initialization

  finalization

  end.

Инициализация и финализация необходимы, потому что в противном случае возникают ошибки связывания, относящиеся к некоторому отсутствующему коду инициализации и финализации. Вызывающий класс:

  unit DLL_Test_Main;

  interface

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

  //{$I Androidapi.inc}

  type
     TForm1 = class(TForm)
      Button_Load: TButton;
      Label1: TLabel;

      procedure Button_LoadClick (Sender: TObject);
      procedure FormCreate(Sender: TObject);

     public
        procedure call_external_function (value: Integer);
     end; // Class: TForm1 //

  var
     Form1: TForm1;

  implementation

  {$R *.fmx}

  procedure TForm1.FormCreate (Sender: TObject);
  begin
     Label1.Text := 'External function not called yet';
  end; // FormCreate //

  procedure TForm1.Button_LoadClick (Sender: TObject);
  begin
     call_external_function (3);
  end; // Button_LoadClick //

  procedure TForm1.call_external_function (value: integer);
  var n: Int32;
  begin
     n := test_1 (value);
     Label1.Text := Format ('%d = test_1 (%d)', [n, value]);
  end; // call_external_function //

  end.

Вместе с родной библиотекойmiditest, Это было построено с использованиемndk-build, Полученная библиотекаlibmiditest.so был скопирован вC:\Users\Public\Documents\RAD Studio\12.0\PlatformSDKs\android-ndk-r8e\platforms\android-14\arch-arm\usr\lib поскольку это место, где Delphi разместил свои собственные библиотеки.

  #include 

  int test_1 (int n) // little test for callability
  {
     return n * n;
  }

Когда я делаюndk-build файлlibmiditest.so производится в подкаталогеlibs\armeabi-v7a, Я скопировал этот файл в\platforms\android-14\arch-arm\usr\lib, Поскольку у меня были некоторые ошибки в начале (неправильные имена и подобные глупые ошибки), я использовалreadelf -AWs libmiditest.so составить список символов и ожидаемую архитектуру библиотеки. Имяtest_1 был в списке символов, как и архитектура arm v7 (я использую Nexus 7 для тестирования). Когда я запускаю программу Delphi, она сразу падает на Android: «К сожалению, DLL_Test_Propject остановился », Изучая вывод adb (см. Ниже), выясняется, что файлlibDLL_Test_Project.so ожидается. Я заменилlibmiditest.so в модуле DLL_external bylibDLL_Test_Project.so и скопировал/usr/lib/libmiditest.so в/usr/lib/libDLL_Test_Project.so, Это не помогло.

Кто-нибудь понимает, почему созданное Delphi приложение пытается загрузить собственную библиотеку? И лучше: есть какие-нибудь предложения, как мне вызвать C-функцию Android через Delphi?

  I/InputReader(  608): Reconfiguring input devices.  changes=0x00000010
  D/dalvikvm(  799): GC_FOR_ALLOC freed 2003K, 15% free 14582K/16964K, paused 29ms, total 29ms
  I/PCKeyboard(  799): Loaded dictionary, len=841005
  I/HK/LatinKeyboardBaseView(  799): onMeasure width=1200
  I/HK/LatinKeyboardBaseView(  799): onMeasure width=1200
  D/Documents( 3358): Used cached roots for com.android.providers.downloads.documents
  D/Documents( 3358): Used cached roots for com.android.externalstorage.documents
  D/Documents( 3358): Used cached roots for com.android.providers.media.documents
  D/Documents( 3358): Used cached roots for com.google.android.apps.docs.storage
  D/Documents( 3358): Update found 7 roots in 28ms
  D/BackupManagerService(  608): Received broadcast Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.embarcadero.DLL_Test_Project flg=0x4000010 (has extras) }
  V/BackupManagerService(  608): addPackageParticipantsLocked: #1
  D/SystemBroadcastService(  987): Received broadcast action=android.intent.action.PACKAGE_ADDED and uri=
  W/ContextImpl(  987): Implicit intents with startService are not safe: Intent { act=com.google.android.gms.games.service.INTENT } android.content.ContextWrapper.startService:494 com.google.android.gms.games.service.GamesIntentService.a:101 com.google.android.gms.games.service.GamesIntentService.b:368
  I/ActivityManager(  608): Delay finish: com.android.vending/com.google.android.finsky.receivers.PackageMonitorReceiver$RegisteredReceiver
  I/ActivityManager(  608): Resuming delayed broadcast
  I/ActivityManager(  608): Delay finish: com.google.android.apps.plus/.service.PackagesMediaMonitor
  I/ActivityManager(  608): Resuming delayed broadcast
  V/GelStubAppWatcher( 3631): onReceive: android.intent.action.PACKAGE_ADDED
  I/Icing.InternalIcingCorporaProvider( 3631): Updating corpora: A: com.embarcadero.DLL_Test_Project, C: MAYBE
  I/ActivityManager(  608): START u0 {flg=0x10800000 cmp=com.estrongs.android.pop/.app.InstallMonitorActivity (has extras)} from pid 3466
  D/dalvikvm(  608): GC_EXPLICIT freed 1385K, 11% free 19671K/22028K, paused 3ms+8ms, total 194ms
  D/dalvikvm(  608): WAIT_FOR_CONCURRENT_GC blocked 24ms
  D/AndroidRuntime( 4437): Shutting down VM
  D/dalvikvm( 4437): GC_CONCURRENT freed 95K, 16% free 560K/660K, paused 0ms+0ms, total 2ms
  W/InputMethodManagerService(  608): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@42c98f48 attribute=null, token = android.os.BinderProxy@42b91f10
  D/dalvikvm( 3631): GC_CONCURRENT freed 560K, 6% free 10268K/10860K, paused 2ms+2ms, total 23ms
  D/AndroidRuntime( 4476):
  D/AndroidRuntime( 4476): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <   D/AndroidRuntime( 4476): CheckJNI is OFF
  D/dalvikvm( 4476): Trying to load lib libjavacore.so 0x0
  D/dalvikvm( 4476): Added shared lib libjavacore.so 0x0
  D/dalvikvm( 4476): Trying to load lib libnativehelper.so 0x0
  D/dalvikvm( 4476): Added shared lib libnativehelper.so 0x0
  D/dalvikvm( 4476): No JNI_OnLoad found in libnativehelper.so 0x0, skipping init
  D/dalvikvm( 4476): Note: class Landroid/app/ActivityManagerNative; has 179 unimplemented (abstract) methods
  D/AndroidRuntime( 4476): Calling main entry com.android.commands.am.Am
  I/ActivityManager(  608): START u0 {flg=0x10000000 cmp=com.embarcadero.DLL_Test_Project/com.embarcadero.firemonkey.FMXNativeActivity (has extras)} from pid 4476
  D/dalvikvm(  608): GC_FOR_ALLOC freed 807K, 12% free 19517K/22028K, paused 63ms, total 63ms
  D/AndroidRuntime( 4476): Shutting down VM
  D/dalvikvm( 4476): GC_CONCURRENT freed 96K, 15% free 586K/684K, paused 0ms+0ms, total 2ms
  D/dalvikvm( 4507): Late-enabling CheckJNI
  I/ActivityManager(  608): Start proc com.embarcadero.DLL_Test_Project for activity com.embarcadero.DLL_Test_Project/com.embarcadero.firemonkey.FMXNativeActivity: pid=4507 uid=10113 gids={50113, 3003, 1028, 1015}
  I/dalvikvm( 4507): Enabling JNI app bug workarounds for target SDK version 9...
  V/PhoneStatusBar(  667): setLightsOn(true)
  D/AndroidRuntime( 4507): Shutting down VM
  W/dalvikvm( 4507): threadid=1: thread exiting with uncaught exception (group=0x41ccbba8)
  E/AndroidRuntime( 4507): FATAL EXCEPTION: main
  E/AndroidRuntime( 4507): Process: com.embarcadero.DLL_Test_Project, PID: 4507
  E/AndroidRuntime( 4507): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.embarcadero.DLL_Test_Project/com.embarcadero.firemonkey.FMXNativ
  eActivity}: java.lang.IllegalArgumentException: Unable to load native library: /data/app-lib/com.embarcadero.DLL_Test_Project-1/libDLL_Test_Project.so
  E/AndroidRuntime( 4507):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
  E/AndroidRuntime( 4507):        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
  E/AndroidRuntime( 4507):        at android.app.ActivityThread.access$800(ActivityThread.java:135)
  E/AndroidRuntime( 4507):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
  E/AndroidRuntime( 4507):        at android.os.Handler.dispatchMessage(Handler.java:102)
  E/AndroidRuntime( 4507):        at android.os.Looper.loop(Looper.java:136)
  E/AndroidRuntime( 4507):        at android.app.ActivityThread.main(ActivityThread.java:5017)
  E/AndroidRuntime( 4507):        at java.lang.reflect.Method.invokeNative(Native Method)
  E/AndroidRuntime( 4507):        at java.lang.reflect.Method.invoke(Method.java:515)
  E/AndroidRuntime( 4507):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
  E/AndroidRuntime( 4507):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
  E/AndroidRuntime( 4507):        at dalvik.system.NativeStart.main(Native Method)
  E/AndroidRuntime( 4507): Caused by: java.lang.IllegalArgumentException: Unable to load native library: /data/app-lib/com.embarcadero.DLL_Test_Project-1/libDLL_Test_Project.so
  E/AndroidRuntime( 4507):        at android.app.NativeActivity.onCreate(NativeActivity.java:183)
  E/AndroidRuntime( 4507):        at com.embarcadero.firemonkey.FMXNativeActivity.onCreate(FMXNativeActivity.java:67)
  E/AndroidRuntime( 4507):        at android.app.Activity.performCreate(Activity.java:5231)
  E/AndroidRuntime( 4507):        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
  E/AndroidRuntime( 4507):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
  E/AndroidRuntime( 4507):        ... 11 more
  W/ActivityManager(  608):   Force finishing activity com.embarcadero.DLL_Test_Project/com.embarcadero.firemonkey.FMXNativeActivity
  I/WindowManager(  608): Screenshot max retries 4 of Token{42a06c48 ActivityRecord{42a42de8 u0 com.embarcadero.DLL_Test_Project/com.embarcadero.firemonkey.FMXNat
  iveActivity t17 f}} appWin=Window{42a1bab8 u0 Starting com.embarcadero.DLL_Test_Project} drawState=4
  W/WindowManager(  608): Screenshot failure taking screenshot for (1200x1920) to layer 21015
  W/ActivityManager(  608): Activity pause timeout for ActivityRecord{42a42de8 u0 com.embarcadero.DLL_Test_Project/com.embarcadero.firemonkey.FMXNativeActivity t17 f}
  E/WindowManager(  608): Starting window AppWindowToken{4308ff58 token=Token{42a06c48 ActivityRecord{42a42de8 u0 com.embarcadero.DLL_Test_Project/com.embarcadero.firemonkey.FMXNativeActivity t17}}} timed out
  I/Process ( 4507): Sending signal. PID: 4507 SIG: 9
  W/InputMethodManagerService(  608): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@42a1abd0 attribute=null, token = android.os.BinderProxy@42b91f10
  I/ActivityManager(  608): Process com.embarcadero.DLL_Test_Project (pid 4507) has died.
  D/Finsky  ( 1567): [1] 5.onFinished: Installation state replication succeeded.

Ответы на вопрос(1)

Ваш ответ на вопрос