Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * This method has been tested on Linux running Ubuntu 12.04
- *
- * 1. Download the Android NDK: http://developer.android.com/tools/sdk/ndk/index.html
- * 2. Extract it somewhere.
- * 3. Download eNet source: http://enet.bespin.org/SourceDistro.html
- * 4. Make a new directory in your Java project's root folder called 'jni'.
- * 5. Extract the eNet source into that directory. If it makes an enet-1.3.5/ directory
- * inside it, move all the files and folders from enet-1.3.5/ dirtectory to jni/
- * 6. Move all the header files from include/ to the jni/ directory.
- * The jni/ directory should now contain the following files and folders:
- *
- * aclocal.m4 ChangeLog config.sub depcomp enet enet.dsp install-sh LICENSE m4 missing
- * protocol.c compress.c configure docs enet64.lib enet.lib list.c Makefile.am packet.c
- * README win32.c callbacks.c config.guess configure.ac Doxyfile enet_dll.cbp host.c
- * libenet.pc.in ltmain.sh Makefile.in peer.c unix.c
- *
- * where enet docs and m4 are directories.
- * 7. Create a jni-wrapper.c file with the following contents:
- */
- /* FILE: jni-wrapper.c */
- #include "enet/enet.h"
- #include "jni.h"
- /* Get your class' mangled function names with:
- * $ javah -classpath /home/vladimir/workspace/TestEnet/bin/classes/ com.example.testenet.MainActivity
- * javah takes -classpath switch. Replace the directory following it with with your project's one.
- * The second argument is the classpath. You can cd to the directory that contains the .java
- * file that declares a native function. In your case, you want to add a
- *
- * public native int enet_initialize();
- *
- * declaration to your .java file **BEFORE** you execute this command.
- * In my case, this produced a com_example_testenet_MainActivity.h file in the
- * src/com/example/testenet/ directory.
- */
- /* You will probably need this. You can call enet_initialize() from here if you want
- * the library to initialize when you load it inside your Java application.
- */
- jint JNI_OnLoad
- (JavaVM *vm, void *reserved)
- {
- printf("Hello, world!\n");
- return JNI_VERSION_1_6;
- }
- /* Now we come to the dreadful name mangling. Calling externally defined (native) functions
- * in Java is not as simple as declaring a function native and loading a correct library.
- * The function name must be propperly formed so that the JavaVM can find it. You can
- * devise this name by yourself. it starts with Java_ then follows the classpath
- * divided with underscores and finally, the function name. If a declared native function
- * also contains an underscore, instead of enet__initialize for example, you write
- * enet_1initialize.
- *
- * javah utility does all this name mangling for you.
- *
- */
- JNIEXPORT jint JNICALL /* This declaration enables the JavaVM to find this function.
- * It returns a jint (because you put int as a return type in the
- * function declaration in your .java file.)
- */
- Java_com_example_testenet_MainActivity_enet_1initialize /* This is the mangled name. It will
- * allow the VM to correctly call
- * **THIS** function when you call
- * enet_initialize() inside your
- * Java class.
- */
- (JNIEnv *env, jobject obj) /* This is what javah generated for us. If a function had an int
- * as an argument, the declaration would be (JNIEnv *env, jclass
- * cls, int anInt). You use these for all sorts of things, but they
- * are not used in this particular function.
- */
- {
- // Now we're inside the wrapper function.
- printf("CALLING enet_initialize()...\n");
- return enet_initialize(); /* This works because jint (what our function is upposed to
- * return) is just typdefed int. More complex stuff requires
- * more complex approach.
- */
- }
- /* END FILE */
- /* 8. Create and Andorid.mk file inside the jni/ directory with the following contents:
- * (This is actually just copied from a NDK sample app. I omitted the licence comment
- * block. Hope I won't be sued for this :))
- *
- * FILE: Android.mk */
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE := enet-jni
- LOCAL_SRC_FILES := callbacks.c compress.c host.c list.c packet.c peer.c protocol.c unix.c win32.c jni-wrapper.c
- include $(BUILD_SHARED_LIBRARY)
- /* END FILE
- *
- * As you can see, it contains all the .c files currently in the jni/ directory,
- * including the jni-wrapper.c file we created previously.
- * 9. cd to the directory where you extracted the Android NDK files.
- * 10. Export the Android project's path to the NDK_BUILD_VARIABLE:
- * $ export NDK_BUILD_VARIABLE=/home/vladimir/workspace/TestEnet/
- * 11. Execute the ndk-build command:
- * $ ./ndk-build
- * It should compile and link it successfully.
- * 12. Now you can add:
- static {
- System.loadLibrary("enet-jni");
- }
- * to your .java file. This is how mine looks (I used a New Android Project from Eclipse):
- * FILE: MainActivity.java */
- package com.example.testenet;
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
- import android.widget.TextView;
- public class MainActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- TextView tv = new TextView(this);
- if (enet_initialize() != 0)
- tv.setText("Error!");
- else
- tv.setText("Enet initialized.");
- setContentView(tv);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.activity_main, menu);
- return true;
- }
- public native int enet_initialize();
- static {
- System.loadLibrary("enet-jni");
- }
- }
- /* END FILE
- *
- * I went through much trouble trying to get it work, but when I set everything up right,
- * I ran this example project and was greeted with a "Enet initialized." message on the
- * emulator screen. Of course, this is just very, very basic stuff (in unix.c, I saw that
- * it's implementation of enet_initialize(), simply returns a 0 :). So, if you were to
- * embark on the adventure of wrapping the existing eNet library with jni to include in your
- * project, you are probably wondering if it's worth it. Quite honestly, I don't think it is.
- * You are better off using different libraries for that.
- * But you will learn a lot if you decide to manually do it (try implementing only the basic
- * stuff you'd need for a client - you don't need to wrap all of the libraries functions, just
- * the one's you'd end up using in your project). Now, if you are interested, you are
- * probably wondering how can one pass more complex stuff between the Java app and the module.
- * I am not that skilled to answer you that, but I've included some links that should be
- * enough to get you started. Enjoy :)
- * LINKS:
- http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html
- http://www.steveolyo.com/JNI/JNI.html
- http://stackoverflow.com/questions/3923299/how-to-pass-c-structs-back-and-forth-to-java-code-in-jni
- http://www.ibm.com/developerworks/java/library/j-jni/
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement