4 votes

DllNotFoundException dans une application Android NDK avec Xamarin

Je veux créer une application Android qui utilise le NDK avec C++.

J'ai créé une nouvelle solution Android App dans Xamarin Studio appelée ndkTest. J'ai ajouté un dossier jni, et j'y ai ajouté ces fichiers :

  • Android.mk
  • Application.mk
  • mon.h
  • test.cpp

Voici le contenu de chacun d'eux :

Android.mk :

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := ndkTest
LOCAL_SRC_FILES := test.cpp
LOCAL_STATIC_LIBRARIES := my

include $(BUILD_SHARED_LIBRARY)

Application.mk :

APP_ABI := armeabi-v7a
APP_STL := stlport_static

mon.h :

#ifndef __MY_H__
#define __MY_H__

#define MY_CONST    1

#ifdef __cplusplus
extern "C"
#endif
short
my_func( short          my_param );

#endif /* __MY_H__ */

test.cpp :

// test.cpp
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include <iostream>
#include <fstream>
#include <vector>

#include "my.h"

#define SOME_CONST     2*MY_CONST
short  some_short;

#ifdef __cplusplus
extern "C"
{
#endif

static void static_func_0()
{
some_short = 0;
}

static void static_func_1()
{
some_short = 1;
}

#ifdef __cplusplus
}
#endif

static void static_print()
{
printf("static_print\n");
printf("some_short = %d\n", some_short);
}

extern "C" short getSomeShort()
{
printf("myExtern\n");
return some_short;
}

C'est là que ça devient intéressant : J'ai installé ndk et l'ai correctement configuré. En ligne de commande, je me place dans le répertoire du projet et j'exécute

ndk-build

Et je reçois cette erreur :

make.exe: *** No rule to make target [path to ndk]/sources/cxx-stl/stlport/test.cpp', needed byobj/local/armeabi/objs/ndkTest/test.o'. Stop.

C'est bizarre, mais peu importe, je peux spécifier le chemin complet de test.cpp dans Android.mk et il se construit :

[armeabi] Compile++ thumb: ndkTest <= test.cpp
[armeabi] SharedLibrary : libndkTest.so
[armeabi] Install : libndkTest.so => libs/armeabi/libndkTest.so

J'ai donc maintenant le fichier .so. Après avoir ajouté ceci au sommet de MainActivity.cs : using System.Runtime.InteropServices; J'ai ajouté ceci :

[DllImport("libndkTest", EntryPoint="getSomeShort")]
static extern short getSomeShort();

Et j'ai ajouté un appel à ça dans OnCreate. J'obtiens un DllNotFoundException . Qu'est-ce que je rate ?

0voto

khumbunix Points 1

Si je devais deviner, je dirais que vous devriez renommer libndkTest en ndkTest dans votre déclaration DllImport.

[DllImport("ndkTest")]
static extern short getSomeShort();

Je ne peux pas actuellement tester votre version mais cela fonctionnait pour moi de cette façon.

Je suppose que vous l'avez déjà fait, mais vous devriez vérifier l'action de construction et l'emplacement de votre bibliothèque, elle devrait être sous lib/your_abi/your_lib.so. Je me souviens m'être tapé la tête pendant 2 jours à cause d'une erreur de chemin de reniflage...

0voto

hundyz Points 1

J'ai trouvé une solution de contournement :

Dans Xamarin Studio, allez dans Options du projet, Build, Android Build, et dans l'onglet Avancé, décochez tous les ABIs supportés sauf armeabi-v7a. Pour une raison quelconque, l'application ne fonctionne pas sur un Samsung S6 utilisant arm64-v8a, alors qu'elle devrait clairement fonctionner.

YMMV

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X