JNI in C++ to read file to jbyteArray

12,096

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:

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

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)!

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;
}
Share:
12,096
Renga
Author by

Renga

Updated on June 04, 2022

Comments

  • Renga
    Renga almost 2 years

    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.

    I read the file in C++ into char* but could not convert into jbyteArray. Please help it.

    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] != '\0'){
            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

    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
    
  • maba
    maba over 11 years
    +1; I would also suggest to use the len variable when creating and setting the byte array instead of fix value 100.
  • MadScientist
    MadScientist over 11 years
    You could use a std::string or std::vector<char> as temporary container.
  • Renga
    Renga over 11 years
    Thank you, Goz and others. error: invalid conversion from char*' to const jbyte*' com_sp_dll_NativeMethods.cpp:: error: initializing argument 4 of `void
  • Renga
    Renga over 11 years
    I got the above mentioned error. Sorry to be pest. I am not familiar ith C++ and JNI data types
  • Goz
    Goz over 11 years
    @Renga: Then edit your original question and post up the errors.
  • Goz
    Goz over 11 years
    @Renga: What you are getting is a linker error. Are you sure you've included all the libraries you need?
  • Renga
    Renga over 11 years
    @Goz: Please let me know how to incude libraries.. I dont use any specific libraries. Is there anything that I need to add? I desperately need your help.
  • Goz
    Goz over 11 years
    @Renga: I don't know anything about your build process. But you are using libraries you are using JNI and STL, for example. Show me how you are building and I may be able to help.
  • Renga
    Renga over 11 years
    @Goz: Can I have your email ID? I can mail you the files.
  • Goz
    Goz over 11 years
    @Renga: All I'm after is your GCC & LD command lines ... or, perhaps, your makefile.
  • Renga
    Renga over 11 years
    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 Is this what you mentioned?
  • maba
    maba over 11 years
    @Renga You shouldn't ask for peoples email. The idea with SO is that everything is public. If anyone finds the answer here useful then it wouldn't be good if some part of it is in somebody's mail box. Use the chat functionality instead. It saves all conversations.
  • Goz
    Goz over 11 years
    @Renga: TBH I'm not really sure whats wrong with that. You may want to create a new question asking specifically how to compile and link JNI code. You'll probably get a better response than asking in the comments here...
  • Renga
    Renga over 11 years
    @Goz: Thanks a lot for all your help. Qmaba: I am sorry. I am new to this forum. I will not do it again. Thanks again.