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

  • Home
  • SEARCH
  • 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 class which I'm serialising to send over a unix socket and
I have a class which implements UserControl. In .NET 2005, a Dispose method is
I have a class which is marked with a custom attribute, like this: public
I have a class which has the following constructor public DelayCompositeDesigner(DelayComposite CompositeObject) { InitializeComponent();
I have a class which looks something like this: public class Test { private
I have a class which inherits from QTreeWidgetItem and I intercept the click event.
I have a class which is not thread safe: class Foo { /* Abstract
I have a class which has many small functions. By small functions, I mean
I have an class which has a enum property and a boolean property, based

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.