java C++中的JNI将文件读取到jbyteArray
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12854333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JNI in C++ to read file to jbyteArray
提问by Renga
I am writing a C++ program in UNIX to generate a shared library which will be called in java using JNI. This C++ program has to read a file in UNIX box then it will have to be converted into jbyteArray
(JNI data type) so that JAVA can use it.
我正在 UNIX 中编写一个 C++ 程序来生成一个共享库,它将使用 JNI 在 java 中调用。这个 C++ 程序必须读取 UNIX 盒中的文件,然后必须将其转换为jbyteArray
(JNI 数据类型),以便 JAVA 可以使用它。
I read the file in C++ into char*
but could not convert into jbyteArray
. Please help it.
我将 C++ 中的文件读入char*
但无法转换为jbyteArray
. 请帮助它。
Code is below::
代码如下:
#include <iostream>
#include <fstream>
#include <stdio.h>
#include "com_sp_dll_NativeMethods.h" // this header file was generated by java
using namespace std;
JNIEXPORT void JNICALL Java_HelloWorld_displayMessage(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
}
JNIEXPORT jbyteArray JNICALL Java_com_sp_dll_NativeMethods_getFile(JNIEnv *env, jobject obj)
{
ifstream fl("/home/rkannan/myFile.txt");
fl.seekg(0, ios::end );
size_t len = fl.tellg();
char *ret = new char[len];
fl.seekg(0, ios::beg);
fl.read(ret, len);
fl.close();
int i = 0;
jbyte *a1 = null;
while(ret[i] != 'bash-3.00$ g++ -I /usr/jdk/instances/jdk1.5.0/include -I /usr/jdk/instances/jdk1.5.0/include/solaris -o libSample.so -shared com_sp_dll_NativeMethods.cpp
Text relocation remains referenced
against symbol offset in file
std::__ioinit 0x550 /var/tmp//ccKCiEKq.o
std::__ioinit 0x554 /var/tmp//ccKCiEKq.o
std::__ioinit 0x588 /var/tmp//ccKCiEKq.o
std::__ioinit 0x58c /var/tmp//ccKCiEKq.o
.rodata (section) 0x204 /var/tmp//ccKCiEKq.o
.rodata (section) 0x208 /var/tmp//ccKCiEKq.o
.rodata (section) 0x244 /var/tmp//ccKCiEKq.o
.rodata (section) 0x248 /var/tmp//ccKCiEKq.o
.rodata (section) 0x2f4 /var/tmp//ccKCiEKq.o
.rodata (section) 0x2f8 /var/tmp//ccKCiEKq.o
std::fpos<__mbstate_t>::operator long long() const0x348 /var/tmp//ccKCiEKq.o
std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)0x400 /var/tmp//ccKCiEKq.o
std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)0x2cc /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::is_open()0x260 /var/tmp//ccKCiEKq.o
std::basic_istream<char, std::char_traits<char> >::read(char*, int)0x39c /var/tmp//ccKCiEKq.o
JNIEnv_::SetByteArrayRegion(_jbyteArray*, int, int, signed char const*)0x468 /var/tmp//ccKCiEKq.o
operator new[](unsigned int) 0x364 /var/tmp//ccKCiEKq.o
std::basic_istream<char, std::char_traits<char> >::seekg(long long, std::_Ios_Seekdir)0x31c /var/tmp//ccKCiEKq.o
std::basic_istream<char, std::char_traits<char> >::seekg(long long, std::_Ios_Seekdir)0x384 /var/tmp//ccKCiEKq.o
std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char> >(std::basic_istream<char, std::char_traits<char> >&, char*)0x2b4 /var/tmp//ccKCiEKq.o
printf 0x20c /var/tmp//ccKCiEKq.o
JNIEnv_::NewByteArray(int) 0x444 /var/tmp//ccKCiEKq.o
std::ios_base::Init::Init() 0x558 /var/tmp//ccKCiEKq.o
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::size() const0x14 /var/tmp//ccKCiEKq.o
std::cout 0x2c0 /var/tmp//ccKCiEKq.o
std::cout 0x2c4 /var/tmp//ccKCiEKq.o
std::cout 0x3f4 /var/tmp//ccKCiEKq.o
std::cout 0x3f8 /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream()0x234 /var/tmp//ccKCiEKq.o
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const0x9c /var/tmp//ccKCiEKq.o
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const0x128 /var/tmp//ccKCiEKq.o
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const0x184 /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode)0x250 /var/tmp//ccKCiEKq.o
std::ios_base::Init::~Init() 0x590 /var/tmp//ccKCiEKq.o
std::basic_ios<char, std::char_traits<char> >::eof() const0x288 /var/tmp//ccKCiEKq.o
unsigned int const& std::min<unsigned int>(unsigned int const&, unsigned int const&)0x44 /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()0x49c /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()0x4ac /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()0x4d4 /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()0x4f8 /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::close()0x2e4 /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::close()0x3ac /var/tmp//ccKCiEKq.o
std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(char const*, std::_Ios_Openmode)0x300 /var/tmp//ccKCiEKq.o
operator delete[](void*) 0x484 /var/tmp//ccKCiEKq.o
std::basic_istream<char, std::char_traits<char> >::tellg() 0x334 /var/tmp//ccKCiEKq.o
_Unwind_Resume 0x508 /var/tmp//ccKCiEKq.o
ld: fatal: relocations remain against allocatable but non-writable sections
collect2: ld returned 1 exit status
'){
cout<<ret[i];
al[i] = ret[i];
i++;
}
jbyteArray result = env->NewByteArray( len);
env->SetByteArrayRegion( result, 0, len, (const jbyte*) ret );
delete[] ret;
return result;
}
The error is as follows
错误如下
env->SetByteArrayRegion( result, 0, 100, ret );
回答by Goz
You don't appear to be setting any byte data to the array. In fact as a jbyte is typedef'd to a char you can directly set your char array in setByteArrayRegion as follows:
您似乎没有为数组设置任何字节数据。事实上,当 jbyte 被 typedef 到一个字符时,你可以直接在 setByteArrayRegion 中设置你的字符数组,如下所示:
JNIEXPORT jbyteArray JNICALL Java_com_sp_dll_NativeMethods_getFile
(JNIEnv *env, jobject obj)
{
ifstream fl("/home/rkannan/myFile.txt");
fl.seekg(0, ios::end );
size_t len = fl.tellg();
char *ret = new char[len];
fl.seekg(0, ios::beg);
fl.read(ret, len);
fl.close();
jbyteArray result = env->NewByteArray( len);
env->SetByteArrayRegion( result, 0, len, (const jbyte*)ret );
delete[] ret;
return result;
}
Edit: Also, assuming that the al[i] should be a1[i] you are doing something very dangerous as you are not allocating space for a1. Basically doing as I suggest above means you can get rid of that entire loop. Also don't forget to delete the C++ Array when you have finished with it (ie copied it into the jByteArray)!
编辑:另外,假设 al[i] 应该是 a1[i] 你正在做一些非常危险的事情,因为你没有为 a1 分配空间。基本上按照我上面的建议去做意味着你可以摆脱整个循环。也不要忘记在完成后删除 C++ 数组(即将它复制到 jByteArray)!
##代码##