通过JNI C+&#x2B读取Android Asset File失败了
我用JNI C ++代码制作了Android应用。
要在Android本机代码(C ++
)上创建APK时读取模型文件,我将模型文件放在Assets文件夹中。 (因此,文件路径为my_app/src/main/assets/model.tflite
)
然后,我尝试读取以下代码的模型,但错误已增加:
kotlin
代码>代码:
private val context: Context
get() = getApplication<Application>().applicationContext
asset_manager = context.assets
c ++
代码:
AAssetManager* mgr = AAssetManager_fromJava(env, asset_manager);
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_STREAMING);
__android_log_print(ANDROID_LOG_INFO, "tag", "file name is: %s", filename); <- file name reading is ok
char buf[BUFSIZ];
int nb_read = 0;
FILE* out = fopen(filename, "w"); <- out has null FILE*
while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
fwrite(buf, nb_read, 1, out);
fclose(out);
AAsset_close(asset);
}
AAssetDir_close(assetDir);
logcat
:
2022-06-19 22:45:54.449 12180-12180/com.my.first.app I/tag: file name is: model.tflite
2022-06-19 22:45:54.449 12180-12180/com.my.first.app A/libc: FORTIFY: fwrite: null FILE*
2022-06-19 22:45:54.450 12180-12180/com.my.first.app A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 12180 (st.app), pid 12180 (st.app)
为什么fopen(fileName,“ w”)
返回null
?看来aassetManager
是有效的。
I have made android app with jni C++ code.
To read model file while creating apk on android native code(C++
), I placed the model file in assets folder. (so file path is my_app/src/main/assets/model.tflite
)
Then, I tried to read the model with following code but an error has raised:
Kotlin
code:
private val context: Context
get() = getApplication<Application>().applicationContext
asset_manager = context.assets
C++
code:
AAssetManager* mgr = AAssetManager_fromJava(env, asset_manager);
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_STREAMING);
__android_log_print(ANDROID_LOG_INFO, "tag", "file name is: %s", filename); <- file name reading is ok
char buf[BUFSIZ];
int nb_read = 0;
FILE* out = fopen(filename, "w"); <- out has null FILE*
while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
fwrite(buf, nb_read, 1, out);
fclose(out);
AAsset_close(asset);
}
AAssetDir_close(assetDir);
logcat
:
2022-06-19 22:45:54.449 12180-12180/com.my.first.app I/tag: file name is: model.tflite
2022-06-19 22:45:54.449 12180-12180/com.my.first.app A/libc: FORTIFY: fwrite: null FILE*
2022-06-19 22:45:54.450 12180-12180/com.my.first.app A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 12180 (st.app), pid 12180 (st.app)
Why does fopen(filename, "w")
return null
? It seems that AAssetManager
is work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
多亏了@botje,我可以按以下方式将
model.tflite
加载到资产中:Thanks to @Botje, I can load the
model.tflite
in assets by this way:Looks like you want to combine this loading code to load the asset into a memory buffer and then use the
然后稍后将其使用为:
注意:this will> will 泄漏内存,因为tflite拥有所有权缓冲区。
Looks like you want to combine this loading code to load the asset into a memory buffer and then use the
BuildFromAllocation
method:and then use it later as:
Note: this will leak memory, as TFlite takes ownership of the buffer.