Andy Matos
Andy Matos

Reputation: 1

Failed to pass assetManager from java to c++ by using JNI

I'd like to using some asset files of my app in native c++ code, so I have some testing code like follows:

Java

package com.example.andy.textureviewtest;
import ...

public class MainActivity extends AppCompatActivity {

    private AssetManager assetManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
        assetManager = getAssets();
        generateAssets(assetManager);
    }

    public native String stringFromJNI();

    public native int generateAssets(AssetManager assetManager);

    static {
        System.loadLibrary("native-lib");
    }
}

C++

#include <jni.h>
#include <string>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android/log.h>

JNIEXPORT jstring JNICALL Java_com_example_andy_textureviewtest_MainActivity_stringFromJNI(
    JNIEnv* env,
    jobject /* this */) {
  std::string hello = "Hello from C++";
  return env->NewStringUTF(hello.c_str());
}

JNIEXPORT jint JNICALL Java_com_example_andy_textureviewtest_MainActivity_generateAssets(
    JNIEnv* env,jobject thiz,jobject assetManager) {
  AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
  AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
  const char* filename = (const char*)NULL;
  while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
    AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_UNKNOWN);
    off_t bufferSize = AAsset_getLength(asset);
}
  return 0;
}

but when my app runs, I only got this error:

java.lang.UnsatisfiedLinkError: No implementation found for int com.example.andy.textureviewtest.MainActivity.generateAssets(android.content.res.AssetManager) (tried Java_com_example_andy_textureviewtest_MainActivity_generateAssets and Java_com_example_andy_textureviewtest_MainActivity_generateAssets__Landroid_content_res_AssetManager_2)

Anything wrong here that I might have missed?

Upvotes: 0

Views: 1453

Answers (1)

Alex Cohn
Alex Cohn

Reputation: 57173

Your C++ functions probably are missing

extern "C"

prefix. Their exported names are mangled by the C++ compiler, and JNI fails to resolve them.

Upvotes: 1

Related Questions