Question

I have a very simple CPP class and a C function that is called from my CPP class. Also I'm using SWIG to generate the glue code between JAVA and native.

But when I'm trying to compile it with NDK if fails to compile with the following error:

Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 16 in ./AndroidManifest.xml    
[armeabi] Compile++ thumb: swig_module <= swig_wrap.cpp
[armeabi] Compile++ thumb: swig_module <= myclass.cpp
[armeabi] Compile thumb  : swig_module <= test.c
[armeabi] StaticLibrary  : libstdc++.a
[armeabi] SharedLibrary  : libswig_module.so
/Users/xxxxxxx/Documents/Android/adt-bundle-mac-x86_64-20131030/ndk/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/swig_module/src/myclass.o: in function myclass::foo():jni/src/myclass.cpp:6: error: undefined reference to 'mult(int, int)'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/libswig_module.so] Error 1

So here is the code:

**test.h**
int mult(int a, int b);

**test.c**
#include "test.h"

int mult(int a, int b)
{
    return a * b;
}

**myclass.h**
class myclass
{
public:
    int foo();
};

**myclass.cpp**
#include "myclass.h"
#include "test.h"

int myclass::foo()
{
    return mult(5,5);
}

**Android.mk**
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := swig_module 
LOCAL_SRC_FILES := swig_wrap.cpp src/myclass.cpp src/test.c

include $(BUILD_SHARED_LIBRARY)

the swig_wrap.cpp file is generated from SWIG with the following command

swig -java -c++ -package com.example.swigtest.swiggen -outdir src/com/example/swigtest/swiggen/ -o jni/swig_wrap.cpp jni/swig.i

**swig.i**
%module swig_module

%{
    #include "src/myclass.h"
%}

%include "src/myclass.h" 

I can compile the native code with g++ fine with no issues, but with NDK it isn't working.

I really need this to work because I would like to use the SWIG directors feature for callback (which I don't show here just to keep things as simple as possible).

Any help is appreciated.

Was it helpful?

Solution

You are building test.c with C compiler, C++ code cant see C functions unless you add extern "C" to let the C++ linker know it is C.

Do this:

test.h:

#ifdef __cplusplus
#define EXTERN extern "C"
#else
#define EXTERN 
#endif

EXTERN int mult(int a, int b);

OTHER TIPS

Another way to do it is to use extern "C" with the #include in the .cpp file. For the same reasons as the other answer. This way when the C header file is included the whole thing is wrapped inside extern "C" so all the functions are recognizable by C++.

Make your myclass.cpp file :

#include "myclass.h"
*other c++ includes here*

extern "C" {
#include "test.h"
*other c includes here*
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top