Linking shared object library without headers with NDK in Android Studio
我有一个为
我的库是用Rust编写的,所以没有头文件,我想通过cpp文件在其中调用函数,但似乎无法正确链接库。为了测试,我做了一个简单的函数:
锈
1 2 3 4 | #[no_mangle] pub extern fn rust_test() -> c_int { 82 as c_int } |
C ++
1 2 3 4 5 6 7 8 9 10 11 12 | extern"C" { // Test for calling rust function int rust_test(); jint Java_com_fureality_faceblaster_MainActivity_testRustLaunch(JNIEnv* env, jobject thiz) { return rust_test(); } } // End extern |
Android.mk
1 2 3 4 5 6 7 8 9 10 11 12 | LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := faceblaster-engine LOCAL_SRC_FILES := ../jniLibs/$(TARGET_ARCH_ABI)/libfaceblaster-engine.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := faceblaster LOCAL_SRC_FILES := gl-tests.cpp LOCAL_SHARED_LIBRARIES := faceblaster-engine include $(BUILD_SHARED_LIBRARY) |
错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /home/nathan/Development/projects/faceblaster-android/app/src/main/jni/gl-tests.cpp Error:(23) undefined reference to `rust_test' Error:error: ld returned 1 exit status make: *** [/home/nathan/Development/projects/faceblaster-android/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/libfaceblaster.so] Error 1 Error:Execution failed for task ':app:compileDebugNdk'. > com.android.ide.common.internal.LoggedErrorException: Failed to run command: /home/nathan/Development/bin/android-ndk-r10d/ndk-build NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/home/nathan/Development/projects/faceblaster-android/app/build/intermediates/ndk/debug/Android.mk APP_PLATFORM=android-21 NDK_OUT=/home/nathan/Development/projects/faceblaster-android/app/build/intermediates/ndk/debug/obj NDK_LIBS_OUT=/home/nathan/Development/projects/faceblaster-android/app/build/intermediates/ndk/debug/lib APP_ABI=all Error Code: 2 Output: /home/nathan/Development/projects/faceblaster-android/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/faceblaster//home/nathan/Development/projects/faceblaster-android/app/src/main/jni/gl-tests.o: In function `Java_com_fureality_faceblaster_MainActivity_testRustLaunch': /home/nathan/Development/projects/faceblaster-android/app/src/main/jni/gl-tests.cpp:23: undefined reference to `rust_test' collect2: error: ld returned 1 exit status make: *** [/home/nathan/Development/projects/faceblaster-android/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/libfaceblaster.so] Error 1 |
我不知道我的makefile没有被提取还是正确?有人对如何正确链接此.so文件和注册我要使用的功能有想法吗?
在此先感谢您的帮助!
编辑-添加了Java源代码和rust代码编译方法
爪哇
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class MainActivity extends Activity { // External libraries to load static { System.loadLibrary("faceblaster-engine"); System.loadLibrary("faceblaster"); } // External functions to register public native int testRustLaunch(); @Override protected void onCreate(Bundle savedInstanceState) { // Other stuff omitted for brevity Log.d(TAG,"Testing call..."); int test = testRustLaunch(); Log.d(TAG,"Received:" + test); } } |
锈编译
1 2 3 4 5 6 7 8 9 10 | cargo build --target=arm-linux-androideabi # /project/.cargo/config file [target.arm-linux-androideabi] linker ="/opt/ndk_standalone/bin/arm-linux-androideabi-gcc" # Cargo.toml [lib] name ="faceblaster-engine" crate_type = ["dylib"] |
编辑2
我已经通过
编辑3
事实证明,以下两个答案都有助于解决问题。这主要是因为Android Studio的一部分没有提取我的makefile,生锈代码未正确声明为
试一下:
1 2 3 4 | #[no_mangle] pub extern fn rust_test() -> i32 { 82 // Note simplified implementation } |
要尝试的特定内容是
我还自由地使实际的方法主体更加惯用。
另一个注意事项是您应该更紧密地匹配Rust和C类型。如果要在C语言中使用
您的
然后要在运行时实际加载它,您需要以相反的依赖关系顺序加载库,即:
1 2 | System.loadLibrary("faceblaster-engine"); System.loadLibrary("faceblaster"); |