用C ++编写的JNI将文件读取到jbyteArray

我正在UNIX中编写一个C ++程序来生成一个共享库,该库将使用JNI在java中调用。 这个C ++程序必须在UNIX框中读取文件,然后必须将其转换为jbyteArray (JNI数据类型),以便JAVA可以使用它。

我用C ++将文件读入char*但无法转换为jbyteArray 。 请帮忙。

代码如下::

 #include  #include  #include  #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] != '\0'){ cout<NewByteArray( len); env->SetByteArrayRegion( result, 0, len, (const jbyte*) ret ); delete[] ret; return result; } 

错误如下

 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::operator long long() const0x348 /var/tmp//ccKCiEKq.o std::basic_ostream<char, std::char_traits >& std::operator<< <std::char_traits >(std::basic_ostream<char, std::char_traits >&, char)0x400 /var/tmp//ccKCiEKq.o std::basic_ostream<char, std::char_traits >& std::operator<< <std::char_traits >(std::basic_ostream<char, std::char_traits >&, char const*)0x2cc /var/tmp//ccKCiEKq.o std::basic_ifstream<char, std::char_traits >::is_open()0x260 /var/tmp//ccKCiEKq.o std::basic_istream<char, std::char_traits >::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 >::seekg(long long, std::_Ios_Seekdir)0x31c /var/tmp//ccKCiEKq.o std::basic_istream<char, std::char_traits >::seekg(long long, std::_Ios_Seekdir)0x384 /var/tmp//ccKCiEKq.o std::basic_istream<char, std::char_traits >& std::operator>><char, std::char_traits >(std::basic_istream<char, std::char_traits >&, 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, std::allocator >::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 >::basic_ifstream()0x234 /var/tmp//ccKCiEKq.o std::basic_string<char, std::char_traits, std::allocator >::operator[](unsigned int) const0x9c /var/tmp//ccKCiEKq.o std::basic_string<char, std::char_traits, std::allocator >::operator[](unsigned int) const0x128 /var/tmp//ccKCiEKq.o std::basic_string<char, std::char_traits, std::allocator >::operator[](unsigned int) const0x184 /var/tmp//ccKCiEKq.o std::basic_ifstream<char, std::char_traits >::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 >::eof() const0x288 /var/tmp//ccKCiEKq.o unsigned int const& std::min(unsigned int const&, unsigned int const&)0x44 /var/tmp//ccKCiEKq.o std::basic_ifstream<char, std::char_traits >::~basic_ifstream()0x49c /var/tmp//ccKCiEKq.o std::basic_ifstream<char, std::char_traits >::~basic_ifstream()0x4ac /var/tmp//ccKCiEKq.o std::basic_ifstream<char, std::char_traits >::~basic_ifstream()0x4d4 /var/tmp//ccKCiEKq.o std::basic_ifstream<char, std::char_traits >::~basic_ifstream()0x4f8 /var/tmp//ccKCiEKq.o std::basic_ifstream<char, std::char_traits >::close()0x2e4 /var/tmp//ccKCiEKq.o std::basic_ifstream<char, std::char_traits >::close()0x3ac /var/tmp//ccKCiEKq.o std::basic_ifstream<char, std::char_traits >::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 >::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 

您似乎没有将任何字节数据设置到arrays。 实际上,当一个jbyte为char定义时,你可以直接在setByteArrayRegion中设置你的char数组,如下所示:

 env->SetByteArrayRegion( result, 0, 100, ret ); 

编辑:另外,假设al [i]应该是a1 [i]你正在做一些非常危险的事情,因为你没有为a1分配空间。 基本上按照我的建议进行上述意味着你可以摆脱整个循环。 另外,不要忘记在完成它后删除C ++数组(即将其复制到jByteArray中)!

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