4

I found an article by Vikram Aggarwal that talks about linking Assembly code into Android's NDK, which even has some example code which shows how to connect the C++ code with Assembly. ( see http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html )

My problem is that I want to use the same function but instead of calling it from JNI stub class, I want to call my Assembly function from my private class.

But on compilation, I get the error:

error: 'armFunction' was not declared in this scope

Has anyone tried this or have any idea how to resolve this ?

Edit:

Makefile:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := quake3

# I want ARM, not thumb.
LOCAL_ARM_MODE := arm    

LOCAL_SRC_FILES := \
    multiple.s \
    macros.h \
    math/Vector2.cpp\
    math/Vector3.cpp\
    math/plane.cpp\
    engine/frustum.cpp\
    engine/BoundingVolume.cpp\
    engine/camera.cpp\
    camera-proxy.cpp\

LOCAL_CFLAGS := -DANDROID_NDK \
                -DDISABLE_IMPORTGL \

LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog
#LOCAL_LDLIBS := -llog -lGLESv2

APP_STL := gnustl_static
APP_CPPFLAGS := -S -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a

include $(BUILD_SHARED_LIBRARY)

Function call in cpp file:

void
Java_surreal_quake3_engine_Camera9_nativeGetDirection(JNIEnv* env, jobject thiz)
{
    //Camera* camera = (Camera*) env->GetIntField(thiz, pointerID);

    // get the _Z as the Vector3 java object
    jfieldID vector_fID = env->GetFieldID(cls, "_Z", "Lsurreal/libs/math/Vector3;");
    jobject vector_obj = env->GetObjectField(thiz, vector_fID);

    // call the setter methods on the _vecEye
        //jclass vectorClass = env->FindClass("surreal/libs/math/Vector3");
    jmethodID vector3_set = env->GetMethodID(vector3Class, "set"/*method-name*/, "(FFF)V" /*method-signature*/);
    env->CallVoidMethod(vector_obj, vector3_set, camera->getZ().x, camera->getZ().y, camera->getZ().z);

    int result = armFunction();
}
MByD
  • 135,866
  • 28
  • 264
  • 277
revolutionary
  • 3,314
  • 4
  • 36
  • 53
  • Hi Binyamin, I am simply trying to include the same multiple.s assembley file in my already compiled ndk project. I copy the multiple.s file into my jni folder and my Android.mk file looks like (http://pastie.org/3919681). Now i call the armFunction() from my already running c++ code at the end of the function (see http://pastie.org/3919661) – revolutionary May 16 '12 at 10:15
  • looking at your code, it seems that my old answer is still relevant, so I undeleted it, please take a look. – MByD May 16 '12 at 10:16
  • That's how it looks, see the last line here: http://pastie.org/3919661 – MByD May 16 '12 at 10:18
  • related http://stackoverflow.com/questions/5390509/linking-android-c-code-and-arm-assembler – Ciro Santilli OurBigBook.com Jun 21 '16 at 19:47

1 Answers1

1

Looking at the code of the class, it seems like you call the function, but I can't see any declaration of it, so it is not recognized. So you need to have a declaration of the function's prototype before calling it (in the C++ class):

Something like:

int armFunction(void); // << declaration

void Java_surreal_quake3_engine_Camera9_nativeGetDirection(JNIEnv* env, jobject thiz)
{
    // snip - snap
    int result = armFunction(); // << your function call
}
MByD
  • 135,866
  • 28
  • 264
  • 277
  • okay, when make a prototype of this function in my jni-c++ stub class, i can get things to compile, if i call my assembley function from within the same stub clas e.g. jni/camera-proxy.cpp file. But i want to call my assembley function from my own provate c++ class file e.g. jni/engine/private.cpp – revolutionary May 16 '12 at 10:35
  • D:\Development\Workspace\Quake3\Quake3/jni/engine/frustum.cpp:278: undefined reference to `armFunction(float, float, float, float, float, float)' collect2: ld returned 1 exit status – revolutionary May 16 '12 at 10:36
  • Before we continue, I just want to understand - now it's a new problem? I don't want to confuse them if they are different. – MByD May 16 '12 at 10:39
  • its the same problem, i wanted to call my assembley function from the private c++ class. But initally i could not even call it from the jni-stub class. I can do that now if i add a prototype, but that does not work even if i add the prototype in the private class... – revolutionary May 16 '12 at 10:49
  • So this *is* a different problem. The first one was a compiler error, and now you get a linking error. Note that in the first call to the function, you passed no arguments, while now, for some reason you pass 6 arguments. There's a mismatch. – MByD May 16 '12 at 10:57
  • dude, the no. of arguments are irrelevant. It cannot find the function definition at all. I am keeping my function call the same as my prototype. The problem now is that when i try to call the same function from inside the private class it does'nt work and gives the same error. But i can still call it from the JNI class.... – revolutionary May 16 '12 at 11:03
  • D:\Development\Workspace\Quake3\Quake3/jni/engine/frustum.cpp:279: undefined reference to `armFunction()' – revolutionary May 16 '12 at 11:04
  • try adding `extern "C"` to the function definition. – MByD May 16 '12 at 11:41
  • 1
    Hi binyamin, thanks, that was the way. I created a seperate header file and wrote my assembley function declaration in the extern C. That seems to work now and it compiles and executes. see http://pastie.org/3922622 – revolutionary May 16 '12 at 21:42
  • Hi Binyamin, I have a new problem, I have posted here (http://stackoverflow.com/questions/10662334/pass-parameters-from-c-to-assembley-in-android) please take a look. I have to pass more than four arguments from my c++ function to assembley. Thanks – revolutionary May 19 '12 at 04:50