JNI: How to pass “unsigned char* ” from C++ to java


V

vikas chandra

Hi,

I have a 'unsigned char *' and I want to pass it on to the Java code
using JNI I have tried it in the following way
<code>
jstring test1;
std::string str(reinterpret_cast<const char*>(ucptest));
test1 = env->NewStringUTF(str.c_str());
<code>

where 'ucptest' is 'unsigned char *', ucptest is not null terminated
has ascii values in it . this code works and I can successfully pass
jstring to Java code, but in the load call I am seeing crash in JVM.

What could be the possible reason for the crash? crash is
inconsistence, which could mean memory corruption.

Can someone suggest a better way to pass 'unsigned char*' to Java?

any help is appreciated.

Thanks
 
Ad

Advertisements

M

Martin B.

Hi,

I have a 'unsigned char *' and I want to pass it on to the Java code
using JNI I have tried it in the following way
<code>
jstring test1;
std::string str(reinterpret_cast<const char*>(ucptest));
test1 = env->NewStringUTF(str.c_str());
<code>

where 'ucptest' is 'unsigned char *', ucptest is not null terminated
has ascii values in it . this code works and I can ...

If ucptest is *not* NULL terminated, then your std::string ctor will
already invoke UB.

br,
Martin
 
V

vikas chandra

If ucptest is *not* NULL terminated, then your std::string ctor will
already invoke UB.

br,
Martin

Thanks for the reply Martin.
just before calling the std:string ctor, I have assigned '\0'
by doing
str[len] = '\0';
here 'len' is the variable which has total values in the 'unsigned
char*'

<code>
jstring test1;
std::string str(reinterpret_cast<const char*>(ucptest));
str[len] = '\0';
test1 = env->NewStringUTF(str.c_str());
<code>

Thanks,
Vikas
 
H

Helge Kruse

Martin B. said:
If ucptest is *not* NULL terminated, then your std::string ctor will
already invoke UB.

NULL is a macro found in many compilers defined as a pointer to 0. A string
is not terminated by a pointer but by a special value 0. Usually the term

zero terminated string

is used.

Helge
 
V

Victor Bazarov

NULL is a macro found in many compilers defined as a pointer to 0.

Not by any C++ compiler. And any other compiler is off-topic.

A C++ compiler *usually* defines NULL macro as 0. Perhaps Martin just
made a typo and meant to say "NUL terminated" (where NUL is the symbolic
representation of your "special value 0"). Or maybe "null-terminated"
(lower case, with a hyphen), like in the Standard (see clause 21, the
last subclause).
> A string
is not terminated by a pointer but by a special value 0. Usually the term

zero terminated string

is used.

A Google search for "NULL terminated string" (with quotes) yields about
2 million results whereas "zero terminated string" (with quotes) is less
than 250 thousand. I'd say you need to correct your understanding of
what "usual" is.

V
 
F

Fred Zwarts

vikas chandra said:
If ucptest is *not* NULL terminated, then your std::string ctor will
already invoke UB.

br,
Martin

Thanks for the reply Martin.
just before calling the std:string ctor, I have assigned '\0'
by doing
str[len] = '\0';
here 'len' is the variable which has total values in the 'unsigned
char*'

<code>
jstring test1;
std::string str(reinterpret_cast<const char*>(ucptest));

If ucptest is not 0 terminated, UB has occurred already.
str[len] = '\0';

If len is the length of str, str[len] is out of bound.
 
Ad

Advertisements

V

vikas chandra

Thanks for the reply Martin.
just before calling the std:string ctor, I have assigned '\0'
by doing
     str[len] = '\0';
here 'len' is the variable which has total values in the 'unsigned
char*'
<code>
jstring test1;
std::string str(reinterpret_cast<const char*>(ucptest));

If ucptest is not 0 terminated, UB has occurred already.
str[len] = '\0';

If len is the length of str, str[len] is out of bound.






test1 = env->NewStringUTF(str.c_str());
<code>
Thanks,
Vikas

Hi All,

Thanks for the suggestion's.
as of now, I have got two option now, which I need to put through load
test and see if any of them work.

1) <code>
ucptest[len] = '\0';
jstring str = env->NewStringUTF((const char*) ucptest);
</code>
and then pass the jstring back to java

2) as @Martin.B suggested, the ctor might be causing out of bound
so instead of
<code>
std::string str(reinterpret_cast<const char*>(ucptest));
str[len] = '\0';
</code>

I think I can use
<code>
std::string str(reinterpret_cast<const char*>(ucptest), len);
</code>
here 'len' is the variable which has total values in the 'unsigned
char*', this way ctor will only take required values from the pointer.


I have tried these in my workup code, will need to try it on the
production code base.

Is there any other way to pass the values of 'unsigned char *' to java
code? without doing casting

Thanks,
Vikas
 
H

Helge Kruse

Victor Bazarov said:
Not by any C++ compiler. And any other compiler is off-topic.

You're right. I learned this

/* caution: this is C, not C++ */
#define NULL (void*)0

in my C days. But the C++ compilers provide a define for NULL to keep the
idiom "NULL pointer" alive.


Helge
 
V

Victor Bazarov

You're right. I learned this

/* caution: this is C, not C++ */
#define NULL (void*)0

in my C days. But the C++ compilers provide a define for NULL to keep the
idiom "NULL pointer" alive.

I don't understand your "but" here. Most C++ compilers define NULL as
0, which is just as fine as a null pointer constant as it is as a null
character. You should get no compilation problem writing

#include <cstdlib>
char foo = NULL;

V
 
Ad

Advertisements

J

James Kanze

Nor by any C compiler. Both in C and in C++, NULL is required
to be defined as a null pointer constant. Which has an integral
type in C++, or an integral type or void* type in C. In both
cases, however, it is "magic"; it doesn't point to 0.
I don't understand your "but" here. Most C++ compilers define NULL as
0, which is just as fine as a null pointer constant as it is as a null
character. You should get no compilation problem writing
#include <cstdlib>
char foo = NULL;

You'll get a warning with at least one C++ compiler, g++. (And
NULL is not defined to be 0 with that compiler.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top