C++中的JNI将文件读取到jbyteArray

JNI in C++ to read file to jbyteArray

本文关键字:读取 jbyteArray 文件 中的 JNI C++      更新时间:2023-10-16

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

我将C++中的文件读取为char*,但无法转换为jbyteArray。请帮帮它。

代码如下::

#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] != ''){
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;
}

错误如下

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

您似乎没有为数组设置任何字节数据。事实上,当jbyte被typedef为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;
}