2017-07-23 18 views
0

我想用我在本地C++代码的应用程序的一些资源文件,所以我有一些测试代码类似如下:无法从Java到C++通过assetManager使用JNI

的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; 
} 

但是当我的应用程序运行,我只得到这个错误:

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) 

这里有什么不对吗,我可能错过了?

回答

1

你的C++函数可能缺少

extern "C" 

前缀。它们的导出名称被C++编译器破坏,而JNI无法解析它们。

+0

这就是为什么有'javah'命令来生成正确的头文件。 –

+0

@AndrewHenle:包含头文件对于JNI来说并不是必需的,但它绝对会让生活更轻松。 –

+0

在两个本地函数仍然出现相同错误之前添加extern“C”@ AlexCohn –