Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 660791
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T23:11:45+00:00 2026-05-13T23:11:45+00:00

I have a class in C++ which takes an std::ostream as an argument in

  • 0

I have a class in C++ which takes an std::ostream as an argument in order to continuously output text (trace information). I need to get this text over to the Java side as efficiently as possible. What’s the best way to do this? I was thinking of using a direct buffer, but another method would be to take all the function calls across to Java and do all the processing there, but it seems that I’d need a lot of JNI calls.

If an example could be shown of the exact implementation method, it would be very helpful, or if some code exists already to do this (perhaps part of another project). Another help would be to connect it up directly to a standard Java streaming construct, such that the entire implementation was completely transparent to the developer.

(Edit: I found Sharing output streams through a JNI interface which seems to be a duplicate, but not really of much help — he didn’t seem to find the answer he was looking for)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T23:11:45+00:00Added an answer on May 13, 2026 at 11:11 pm

    The std::ostream class requires a std::streambuf object for its output. This is used by the fstream and stringstream classes, which use the features of ostream by providing a custom implementation of the streambuf class.

    So you can write your own std::streambuf implementation with an overwritten overflow method, buffer the incomming chars in an internal stringbuffer. Every x calls or on eof/newline generate an java-string and call the print method of your java PrintStream.

    An incomplete example class:

    class JavaStreamBuff : std::streambuf
    {
      std::stringstream buff;
      int size;
      jobject handle;
      JNIEnv* env
    
      //Ctor takes env pointer for the working thread and java.io.PrintStream
      JavaStreamBuff(JNIEnv* env, jobject jobject printStream, int buffsize = 50)
      {
         handle = env->NewGlobalRef(printStream);
         this->env = env;
         this->size = size;
      }
      //This method is the central output of the streambuf class, every charakter goes here
      int overflow(int in)
      {
        if(in == eof || buff.size() == size)
       {
         std::string blub = buff.str();
    
         jstring do = //magic here, convert form current locale unicode then to java string
    
         jMethodId id = env->(env->GetObjectClass(handle),"print","(java.lang.String)V");
    
         env->callVoidMethod(id,handle,do);
    
         buff.str("");
        }
        else
        {buff<<in;}
      }
    
      virtual ~JavaStreamBuff()
      {
         env->DeleteGlobalRef(handle);
      }
    }
    

    Missing:

    • Multithread support (the env pointer is only valid for the jvm thread)

    • Error handling (checking for java exceptions thrown)

    • Testing(written within the last 70 min)

    • Native java method to set the printstream.

    On the java side you need a class to convert the PrintStream to a BufferedReader.

    There have to be some bugs there, haven’t spend enough time to work on them.
    The class requires all access to be from the thread it was created in.

    Hope this helps

    Note
    I got it to work with visual studio but I can’t get it to work with g++, will try to debug that later.
    Edit
    Seems that I should have looked for a more official tutorial on this bevore posting my answer, the MSDN page on this topic derives the stringbuffer in a different way.
    Sorry for posting this without testing it better :-(.
    A small correction to the code above in a more or less unrelated point: Just implement InputStream with a custom class and push byte[] arrays instead of Strings from c++.
    The InputStream has a small interface and a BufferedReader should do most of the work.

    Last update on this one, since im unable to get it to work on linux, even with the comments on the std::streambuf class stating that only overflow has to be overwritten.
    This implementation pushes the raw strings into an inputstream, which can be read from by an other thread. Since I am too stupid to get the debugger working its untested, again.

    //The c++ class
    class JavaStreamBuf :public std::streambuf
    {
      std::vector<char> buff;
      unsigned int size;
      jobject handle;
      JNIEnv* env;
    public:
      //Ctor takes env pointer for the working thread and java.io.PrintStream
      JavaStreamBuf(JNIEnv* env, jobject  cppstream, unsigned int buffsize = 50)
      {
         handle = env->NewGlobalRef(cppstream);
         this->env = env;
         this->size = size;
         this->setbuf(0,0);
      }
      //This method is the central output of the streambuf class, every charakter goes here
      virtual int_type overflow(int_type in  = traits_type::eof()){
        if(in == std::ios::traits_type::eof() || buff.size() == size)
        {
            this->std::streambuf::overflow(in);
             if(in != EOF)
                 buff.push_back(in);
    
             jbyteArray o = env->NewByteArray(buff.size());
             env->SetByteArrayRegion(o,0,buff.size(),(jbyte*)&buff[0]);
             jmethodID id = env->GetMethodID(env->GetObjectClass(handle),"push","([B)V");
    
             env->CallVoidMethod(handle,id,o);
             if(in == EOF)
                 env->CallVoidMethod(handle,id,NULL);
    
             buff.clear();
        }
        else
        {
            buff.push_back(in);
        }
    
        return in;
      }
    
      virtual ~JavaStreamBuf()
      {
          overflow();
          env->DeleteGlobalRef(handle);
      }
    
    //The java class
    /**
     * 
     */
    package jx;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InterruptedIOException;
    import java.nio.ByteBuffer;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @author josefx
     *
     */
    public class CPPStream extends InputStream {
    
        List<Byte> data = new ArrayList<Byte>();
        int off = 0;
        private boolean endflag = false;
        public void push(byte[] d)
        {
            synchronized(data)
            {
                if(d == null)
                {
                    this.endflag = true;
                }
                else
                {
                    for(int i = 0; i < d.length;++i)
                    {
                        data.add(d[i]);
                    }
                }
            }
        }
        @Override
        public int read() throws IOException 
        {
            synchronized(data)
            {
    
                while(data.isEmpty()&&!endflag)
                {
    
                    try {
                            data.wait();
                        } catch (InterruptedException e) {
                            throw new InterruptedIOException();
                        }
                }
            }
            if(endflag)return -1;
            else return data.remove(0);
        }
    }
    

    Sorry for wasting so much space^^(and time :-().

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a class which constructor takes a Jakarta enums . I'm trying to
I have a repository Class which takes in a ObjectContext called TestDB. I when
I have a class A which takes a reference of B in its constructor.
I have a Login Class which has a function: isCorrect() that takes username and
I have a class which takes an IEnumerable constructor parameter which I want to
I have class which have one public method Start , one private method and
I have class Money which is an @Embeddable @Embeddable public class Money implements Serializable,
I have class A which extends the Activity class. This class is in package
I have class World which manages creation of object... After creation it calls afterCreation
I have class Employee which is something like this. class Emp { int EmpID;

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.