JNI Help

So I am trying to wrap Flatbuffers with JNI so I can dynamically return the contents of a buffer as a JSON string using the FBS libs. I have the below code and I keep getting and error of:
1
2
3
4
5
6
JRE version: Java(TM) SE Runtime Environment (8.0_60-b27) (build 1.8.0_60-b27)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.60-b23 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [libc++.1.dylib+0x3df93]  _ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm+0x1b
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
      const char *file_identifier = env->GetStringUTFChars(schemaId, 0);
      int len = env->GetArrayLength (bb);

      char * dataPtr = (char*)env->GetByteArrayElements(bb,0);

      std::string* text;


      flatbuffers::Parser parser;
      bool ok = parser.Parse(file_identifier) && GenerateText(parser,dataPtr,text);
      if(ok){
        int byteCount = text->length();
        const jbyte* pNativeMessage = reinterpret_cast<const jbyte*>(text->c_str());
        jbyteArray bytes = env->NewByteArray(byteCount);
        env->SetByteArrayRegion(bytes, 0, byteCount, pNativeMessage);
        env->ReleaseByteArrayElements(bb,(jbyte*)dataPtr,JNI_ABORT);
        return bytes;
      }

      //return (*env).NewStringUTF(text->c_str());
      return env->NewByteArray(0);


When I try just doing the NewStringUTF call it never returns which is why I thought trying bytes may help. Any assistance here? I am pretty terrible at c/c++
The error says that control is inside std::string::reserve(). I don't see any call to reserve() in the code you've posted.
Post GenerateText().
1
2
3
4
5
6
7
8
9
10
  std::string &text = *_text;
  FLATBUFFERS_ASSERT(parser.root_struct_def_);  // call SetRootType()
  text.reserve(1024);               // Reduce amount of inevitable reallocs.
  auto root = parser.opts.size_prefixed ?
      GetSizePrefixedRoot<Table>(flatbuffer) : GetRoot<Table>(flatbuffer);
  if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) {
    return false;
  }
  text += NewLine(parser.opts);
  return true;


FYI. Ive confirmed its getting into the ok block and seems to fail on const jbyte* pNativeMessage = reinterpret_cast<const jbyte*>(text->c_str());
In the future, when posting code don't omit the function signature and terminating brace. Others shouldn't have to guess the types and names of parameters.

I assume that _text, on line 1, is the parameter that took the value of the 'text' pointer, declared on line 6 in your previous post.
You never initialized that pointer to anything, so it's invalid (it points to nothing). When you call std::string::reserve() on line 3, the function tries to work on a piece of memory that's not an std::string, and the program eventually crashes.

I recommend this rewrite:

1
2
3
4
//std::string* text; (Line 6 in your first post.)
std::string text;

//You'll have to fix the code after this to treat text as an object rather than a pointer. 
Since GenerateText() doesn't work if the text pointer is invalid, and you convert it to a reference anyway, you should just make GenerateText() accept a reference:
1
2
3
4
5
return_type GenerateText(/*other arguments*/, std::string &text){
    //std::string &text = *_text; You don't need this line anymore.

    //...
}
Sorry copy and paste error on the generate text:
1
2
3
4
5
6
7
8
9
10
11
12
13
bool GenerateText(const Parser &parser, const void *flatbuffer,
                  std::string *_text) {
  std::string &text = *_text;
  FLATBUFFERS_ASSERT(parser.root_struct_def_);  // call SetRootType()
  text.reserve(1024);               // Reduce amount of inevitable reallocs.
  auto root = parser.opts.size_prefixed ?
      GetSizePrefixedRoot<Table>(flatbuffer) : GetRoot<Table>(flatbuffer);
  if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) {
    return false;
  }
  text += NewLine(parser.opts);
  return true;
}


The problem is that the thing I want is the text not the return(which is just rue or false). This is a Flatbuffer lib which I guess I can change but would there be an alternative?
Huh? I don't follow. I just suggested that you change the third parameter of GenerateText(), not the return type.

If you can't change GenerateText() then that's fine. It was just a suggestion. The bug is that the pointer in your first function is uninitialized. That's what you have to change to fix it.
I guess I could initialize the string to...
Note that I posted a reply just before your last post. I'm letting you know because you might not see it otherwise.
helios - Thanks for the help. I initialized the pointer and all is well now. Given that GenerateText is a 3 party API and is leveraged in way to many other places I decided to leave it along
Topic archived. No new replies allowed.