2

I created a shared visual c++ cross platform mobile library in visual studio 2017 for iOS, UWP, and Android. I was successful able to create a Windows RT Component wrapper for the library to use in a C# UWP. I removed the iOS library as I did not need it. All that remain is the Android project. Currently I am struggling how to write a wrapper for the shared library and import it into android studio. I looked the documentation provided on MSDN, but it goes more in depth on creating a cross platform c++ application and not enough detail on how to leverage the shared static libs.

RandString.java:

package com.myapplication;

/**
 * Created by yorel56 on 7/26/2017.
 */

public class RandString {
    static{
        System.loadLibrary("libRandString");
    }
    public native String GetString();
    public native String GetString(int index);
}

.so files produces by VS2017 project

build.gradle (module):

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.myapplication"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
    sourceSets.main {
        jni.srcDirs = [] //disable automatic ndk-build call
        jniLibs.srcDir 'src/main/libs/' //integrate your libs from libs instead of jniLibs
    }

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn(nativeLibsToJar)
    }

    task ndkBuild(type: Exec, description: 'compile native code') {
        def ndkDir = "C:\\Users\\yorel56\\AppData\\Local\\Android\\sdk\\ndk-bundle"
        workingDir "src/main/jni"
        commandLine "$ndkDir/ndk-build"
    }

    task nativeLibsToJar(type: Jar, description: 'create a jar archive of the native libs') {
        destinationDir file("$buildDir/native-libs")
        baseName 'native-libs'
        extension 'jar'
        from fileTree(dir: 'libs', include: '**/*.so')
        into 'lib/'
    }
    nativeLibsToJar.dependsOn {
        ndkBuild  // comment that, when you don't want to rerun ndk-build script
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
}

The error i am getting currently is that 'native' is not allowed here, and when i choose to let Android Studio fix it by creating a function in native_lib.cpp, I continue to get errors. I tried following the documentation here.

Trejon House
  • 187
  • 2
  • 13
  • I am trying to utilize the VS templates for creating a c++ cross platform mobile shared lib, I was able to use the lib for a UWP project, but am having troubles following suite for Android. The documentation regarding this on MSDN leans more towards creating a full cross platform c++ mobile project which i am not. I am developing in native, but want a particular shared feature to be written in c++. – Trejon House Jul 26 '17 at 14:30
  • So, basically, you have a native Android Java app and you're trying to call out to the C++ library you wrote using JNI? What problems were you having with it? What did you try, and what went wrong? Can you create a [mcve] showing the relevant parts of your code and show any exceptions or error messages you were getting? – EJoshuaS - Stand with Ukraine Jul 26 '17 at 14:35
  • 1
    Correct, does the above help? – Trejon House Jul 26 '17 at 15:20
  • The C/C++ functions on the native side must be declared with some modifiers and with a special strict syntax. If you have not already done so you should install the Hello_JNI Android Studio example project or something similar and play with it – from56 Jul 26 '17 at 15:25
  • Yes, the edit is a big improvement. – EJoshuaS - Stand with Ukraine Jul 26 '17 at 20:02

1 Answers1

0

You can use the libRandString.so which was built with Visual Studio; you don't need the externalNativeBuild block and not ndkBuild task and not the nativeLibsToJar task in your build.gradle. Android Studio will pick up the prebuilt files from jniLibs directory and pack them into the APK for you.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • I'm now getting the following exception java.lang.UnsatisfiedLinkError, stating librandstring.so could not be found – Trejon House Jul 26 '17 at 19:07
  • 1
    I hope the error message is for `libRandString.so` with correct capitalization. This would mean that you cleaned up your **build.gradle** a bit too much. – Alex Cohn Jul 27 '17 at 07:11