Android/App개발2009. 9. 7. 12:54
http://groups.google.com/group/android-ndk/browse_thread/thread/4bc383030ba0a13b/9a77365dd5741d16

Using SWIG in combination with the Android NDK
  메시지 5개 - 모두 접기
Maarten Wijnants  
프로필 보기  
 (1 사용자)  추가옵션 7월6일, 오후11시40분
Hi all, 

I have been experimenting with using native code on the Android 
platform for a few days now, and I am still facing a number of 
problems. 

Let's start with my successes so far. I have tested the sample 
applications included in the Android NDK, and they work perfectly. I 
have also already been able to write a small C library and invoke its 
methods on Android through the NDK build tools and the .mk build 
files. 

My goal however is to access the functionality of an (existing) C++ 
library on the Android platform. The library contains a number of 
classes and I would like to be able to use the library on Android as 
on other platforms (i.e. win32 and unix). Instead of completely 
converting the code to Java, I would like to use it as a native 
library and invoke its functionality through JNI. 

To the best of my knowledge, the most straightforward way to do so 
would be to use SWIG (the Simplified Wrapper and Interface Generator, 
http://www.swig.org/). Please correct me if I am wrong in this 
statement as I am far from an expert in the field of Java programming. 
Using SWIG allows programmers to work with the classes implemented in C 
++ libraries in other languages, including Java. I have tested this on 
win32 and it worked perfectly. 

On Android however, I have up till now not been able to achieve the 
same outcome. It appears to me the problem is that the implementation 
of the native methods cannot be located in the native library. I could 
however be wrong in this assessment. 

Here is my source code. First there is the "native" C++ class, which 
is implemented in files newtestclass.h and newtestclass.cpp as 
follows: 

newtestclass.h 
------------------- 

#ifndef NEWTESTCLASS_H 
#define NEWTESTCLASS_H 

class NewTestClass 

public: 
        NewTestClass(); 
        ~NewTestClass(); 

        void setX(const int x); 
        int getX() const; 
private: 
        int m_x; 

}; 

#endif // NEWTESTCLASS_H 

newtestclass.cpp 
---------------------- 

#include "newtestclass.h" 

NewTestClass::NewTestClass() : m_x(0) 



NewTestClass::~NewTestClass() 



void NewTestClass::setX(const int x) 

        m_x = x; 



int NewTestClass::getX() const 

        return m_x; 



As you can see this is pretty straightforward C++ code, to make sure 
the problems are not being caused by advanced C++ constructs. 

As instructed in the SWIG tutorial, I have written a SWIG interface 
file for this class. The contents is as follows: 

newtestclass.i 
------------------- 

%module newtestclassmodule 
%{ 
#include "newtestclass.h" 
%} 

%include "newtestclass.h" 

Again very simple. On this interface class, I invoke the swig tool as 
follows: 

swig -c++ -o newtestclass_wrap.cpp -package com.example.newtest -java 
newtestclass.i 

which generates the file newtestclass_wrap.cpp. If desired/needed, I 
can provide the contents of this file. Files newtestclass.cpp and 
newtestclass_wrap.cpp are added to the LOCAL_SRC_FILES variable of my 
Android.mk build file. Compiling the native library using the NDK make 
tool succeeds and generates the library libnewtest.so (as the name of 
my NDK module is "newtest"). 

Besides the newtestclass_wrap.cpp file, the swig tool also generates a 
number of .java files which contain the Java implementation of the 
NewTestClass class. As is expected, each memberfunction of this Java 
class simply invokes its corresponding native method. This 
implementation seems correct to me. 

Finally, I attempt to use the Java NewTestClass inside the onCreate 
method of an Android activity class as follows: 

public class RunMe extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 

        System.loadLibrary("newtest"); 

        NewTestClass ntc = new NewTestClass(); 

        TextView tv = new TextView(this); 
        tv.setText("Returned value = " + ntc.getX()); 
        setContentView(tv); 
    } 



I compile and run the Android activity class using the Eclipse ADT 
plug-in. When executing the Android application, LogCat output 
suggests the libnewtest.so library is loaded successfully. However I 
do get some warnings: 

D/dalvikvm( 2027): Trying to load lib /data/data/com.example.newtest/ 
lib/libnewtest.so 0x43597078 
D/dalvikvm( 2027): Added shared lib /data/data/com.example.newtest/lib/ 
libnewtest.so 0x43597078 
D/dalvikvm( 2027): No JNI_OnLoad found in /data/data/ 
com.example.newtest/lib/libnewtest.so 0x43597078 
D/dalvikvm( 2027): +++ not scanning '/system/lib/libwebcore.so' for 
'new_NewTestClass' (wrong CL) 
D/dalvikvm( 2027): +++ not scanning '/system/lib/libmedia_jni.so' for 
'new_NewTestClass' (wrong CL) 
D/dalvikvm( 2027): +++ not scanning '/system/lib/libwebcore.so' for 
'NewTestClass_getX' (wrong CL) 
D/dalvikvm( 2027): +++ not scanning '/system/lib/libmedia_jni.so' for 
'NewTestClass_getX' (wrong CL) 

As soon as the application tries to instantiate a NewTestClass object 
in the onCreate method, the application terminates and I get the 
following LogCat dump: 

I/DEBUG   (  539): *** *** *** *** *** *** *** *** *** *** *** *** *** 
*** *** *** 
I/DEBUG   (  539): Build fingerprint: 'generic/sdk/generic/:1.5/ 
CUPCAKE/148875:eng/test-keys' 
I/DEBUG   (  539): pid: 2027, tid: 2027  >>> com.example.newtest <<< 
I/DEBUG   (  539): signal 7 (SIGBUS), fault addr 00000000 
I/DEBUG   (  539):  r0 42382b49  r1 4359d428  r2 00000000  r3 00000000 
I/DEBUG   (  539):  r4 be9a4540  r5 00000004  r6 804005f0  r7 41049d10 
I/DEBUG   (  539):  r8 be9a451c  r9 41049d04  10 41049cf4  fp 00000000 
I/DEBUG   (  539):  ip 804005f0  sp be9a4508  lr 80400604  pc 
804005e8  cpsr 80000010 
I/DEBUG   (  539):          #00  pc 000005e8  /data/data/ 
com.example.newtest/lib/libnewtest.so 
I/DEBUG   (  539):          #01  pc 00000600  /data/data/ 
com.example.newtest/lib/libnewtest.so 
I/DEBUG   (  539):          #02  pc 0000e3b4  /system/lib/libdvm.so 
I/DEBUG   (  539): stack: 
I/DEBUG   (  539):     be9a44c8  000000da 
I/DEBUG   (  539):     be9a44cc  000001b8 
I/DEBUG   (  539):     be9a44d0  00003071 
I/DEBUG   (  539):     be9a44d4  afe0af93  /system/lib/libc.so 
I/DEBUG   (  539):     be9a44d8  804005f0  /data/data/ 
com.example.newtest/lib/libnewtest.so 
I/DEBUG   (  539):     be9a44dc  00000006 
I/DEBUG   (  539):     be9a44e0  afe3c980 
I/DEBUG   (  539):     be9a44e4  afe39dd0 
I/DEBUG   (  539):     be9a44e8  0000a000  [heap] 
I/DEBUG   (  539):     be9a44ec  00000088 
I/DEBUG   (  539):     be9a44f0  42382b49 
I/DEBUG   (  539):     be9a44f4  00000000 
I/DEBUG   (  539):     be9a44f8  0018cbe8  [heap] 
I/DEBUG   (  539):     be9a44fc  000e1940  [heap] 
I/DEBUG   (  539):     be9a4500  df002777 
I/DEBUG   (  539):     be9a4504  e3a070ad 
I/DEBUG   (  539): #01 be9a4508  00000000 
I/DEBUG   (  539):     be9a450c  00000000 
I/DEBUG   (  539):     be9a4510  00000002 
I/DEBUG   (  539):     be9a4514  ad00e3b8  /system/lib/libdvm.so 
I/ActivityManager(  570): Process com.example.newtest (pid 2027) has 
died. 
D/Zygote  (  541): Process 2027 terminated by signal (7) 

I hope my explanation has been sufficiently elaborate. Has anyone any 
experience on using SWIG on the Android platform and could point out 
what is wrong with my approach? 

Many thanks in advance, 
Maarten Wijnants 


    작성자에게 답글    전달  
Maarten Wijnants  
프로필 보기  
 추가옵션 7월9일, 오후8시42분
As I did not find any solution to this strange problem, I tried 
compiling the native library using the agcc build script (http:// 
plausible.org/andy/agcc). Surprisingly, now everything works as 
expected! In other words, I am able to use my native code in Java as I 
would in a C++ environment. 

Unfortunately however, I still have no clue as to why compilation 
using the Android NDK does not work. If anyone could shed some 
insight, that would be greatly appreciated!


    답글    작성자에게 답글    전달  
Sridhar M  
프로필 보기  
 추가 옵션 7월31일, 오후11시32분

Maarten, 

I have used the SWIG framework on Android and it works. 
From your logs it seems that JNI_OnLoad() is not implemented in your native 
library. Be sure to register all the native JNI methods using JNI_OnLoad() ( 
maybe in newtestclass_wrap.cpp ) 

Regards, 
Sridhar 

On Mon, Jul 6, 2009 at 8:10 PM, Maarten Wijnants <maarten.wijna...@gmail.com 

- 원본 텍스트 보기 -


    답글    작성자에게 답글    전달  
Maarten Wijnants  
프로필 보기  
 추가 옵션 8월26일, 오후9시01분
Hello Sridhar, 

Many thanks for your reply! I am sorry I did not respond sooner, I 
only just noticed someone replied on my question. 

On 31 jul, 16:32, Sridhar M <sridhar....@gmail.com> wrote: 

> Maarten, 

> I have used the SWIG framework on Android and it works. 
> From your logs it seems that JNI_OnLoad() is not implemented in your native 
> library. Be sure to register all the native JNI methods using JNI_OnLoad() ( 
> maybe in newtestclass_wrap.cpp ) 

Indeed I did not implement the JNI_OnLoad method. I saw LogCat 
printing a warning about this, but adding the method did not help me. 
Maybe I did something wrong in the JNI_OnLoad implementation, I'm not 
sure. Anyway, using the agcc build script, I was able to successfully 
get SWIG to work, WITHOUT the JNI_OnLoad method. So I am still not 
really sure whether native JNI method registering is absolutely 
necessary. 

> > Regards, 
> Sridhar 

Once more my gratitude for your reply! Maybe in the future I will 
again look into NDK native library building (instead of using the agcc 
build script). When so, I will definitely look into your suggestion of 
registering native methods in the JNI_OnLoad method. 

Greetz, 
Maarten


    답글    작성자에게 답글    전달  
Sridhar M  
프로필 보기  
 추가 옵션 9월3일, 오후9시30분

Hi Maarten, 

You are welcome! 
For me, the JNI interface started working only after adding JNI_OnLoad() 
Here is a good reference of how the function is written 
http://markmail.org/message/daqhat4un5xlbaze 

Hope it helps. 

Regards, 
Sridhar 

On Wed, Aug 26, 2009 at 5:31 PM, Maarten Wijnants < 

- 원본 텍스트 보기 -


    답글    작성자에게 답글    전달  
Posted by 삼스