Я не особенно разбираюсь в Assembly и ARM, но мне удалось написать несколько подпрограмм, и я хотел бы посмотреть, как они работают на оборудовании Android с поддержкой ARM (Nexus S). Какова процедура включения файла кода сборки в проект Android? Могу ли я назвать его только из собственного кода или из Java?
Как использовать код сборки ARM в проекте Android?
Ответ 1
Вы можете вызывать сборку с Android с использованием Java Native Interface и Android NDK.
Седрик упоминает, используя ключевое слово asm, в то время как я предпочитаю включать исходный код сборки. Я разместил учебник для этого на моем сайте: http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html
Вы можете загрузить исходный код для моего примера и посмотреть, как он работает. Как только вы увидите пример функционирования, его легко изменить в соответствии с вашими потребностями.
Ответ 2
Я думаю, что это должно быть возможно при использовании NDK, который позволяет вам писать код C/С++, упакованный в .apk, а затем запускается на платформе Android.
С этим вы сможете использовать ключевое слово __asm__
в своем коде на C (как указано в примечаниях к выпуску Revision 5b).
Ответ 3
Минимальный пример с встроенным и отдельным исходным файлом
Необходимо соблюдать осторожность, чтобы не собрать исходную сборку под неправильной аркой. Здесь мы используем:
-
#ifdef
в файлах C -
ifeq
onAndroid.mk
Этот пример на GitHub. Протестировано на Ubuntu 16.04, Android NDK 12, Sony Xperia Z3 D6643 (ARMv7) с Android 5.1.1.
JNI/main.c
#include <stdio.h>
#include <jni.h>
#ifdef __arm__
int asm_main(void);
#endif
jstring Java_com_cirosantilli_android_1cheat_ndk_1asm_Main_jniMethod(
JNIEnv* env, jobject thiz) {
enum Constexpr { N = 256 };
char s[N];
size_t cur = 0;
int x = 0;
#ifdef __arm__
cur += snprintf(s + cur, N - cur, "arm ");
/* Inline test. Increment x by 1. */
asm (
"add %0, #1"
: "=r" (x)
: "0" (x)
);
/* Separate source test. Increment x by 1. */
x += asm_main();
#endif
if (x == 2)
cur += snprintf(s + cur, N - cur, "%s", "0");
else
cur += snprintf(s + cur, N - cur, "%s", "1");
return (*env)->NewStringUTF(env, s);
}
JNI/main_asm.S
.text
/* Function that just returns 1. */
.global asm_main
asm_main:
mov r0, #1
bx lr
JNI/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
LOCAL_SRC_FILES := main.c
# http://stackoverflow.com/info/12614417/android-ndk-how-to-get-compiler-architecture-in-android-mk-dynamically
ifneq (,$(filter $(TARGET_ARCH_ABI),armeabi armeabi-v7a))
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) main_asm.S
endif
include $(BUILD_SHARED_LIBRARY)
ком /cirosantilli/android _cheat/ndk_asm/Main.java
package com.cirosantilli.android_cheat.ndk_asm;
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
public class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText(jniMethod());
setContentView(tv);
}
public native String jniMethod();
static {
System.loadLibrary("main");
}
}