Use C++ array directly in Java API requiring byte[] - java-native-interface

As it stands, I have a C++ app that has a unsigned char* buffer containing PCM audio data. I need to call the Android API method AudioTrack.write() on an instance of AudioTrack over JNI (from C++ to Java) with this data, and I would like to avoid making an extra copy in doing so. Can I do this?
AudioTrack accepts as one of its arguments a Java byte[], the argument that should correspond to my PCM data (unsigned char*).
Sorry if this is a duplicate... it's hard to effectively search for this kind of thing.

Something like this should do.
I haven't compiled this, and it would be wise to check the syntax also with the specs.
jbyteArray byteArray;
byteArray = env->NewByteArray(audioDataLength);
env->SetByteArrayRegion(byteArray, 0, audioDataLength , (jbyte*) audioData);
Where audioDataLength is the length of the char* audioData

Related

SAFEARRAY on linux

I'm using a proprietary library on linux that uses SAFEARRAY type in a callback function:
HRESULT Write(SAFEARRAY *Data)
SAFEARRAY is defined in a header file as typedef void SAFEARRAY.
I must define a callback function that will get the data (eg. as *unsigned char) and it's length (eg. as int or size_t) and write the data somewhere.
Something like:
HRESULT MyWrite(SAFEARRAY *Data) {
unsigned char *data = SafeArrayGetData(Data);
size_t length = SafeArrayGetLength(Data);
write_data_somewhere(data, length);
}
And then use it with the library:
ProprietaryLib::ExportThing(thing, MyWrite);
So my question is: How to get the data and it's length on linux, where I have no oaidl.h or oleauto.h header file.
Two thoughts on the matter:
Maybe you've seen it already, but Wine implements SAFEARRAY. Thus you may have a look at
https://github.com/wine-mirror/wine/blob/master/dlls/oleaut32/safearray.c
https://github.com/wine-mirror/wine/blob/master/include/oaidl.idl
https://github.com/wine-mirror/wine/blob/master/include/oleauto.h
It seems to me that to get length and data of the array, it should be fine to just access the members of the struct. For instance, in safearray.c they simply read cbElements at various places, and the method SafeArrayAccessData basically only returns pvData. (In addition, it "locks" the array. The "locking" seems to be a reference counter that is checked when a SAFEARRAY is resized or freed.)
One idea why your MYSAFEARRAY (mentioned in comments) does not work is
that struct packing might interfere. In https://learn.microsoft.com/en-us/cpp/build/reference/zp-struct-member-alignment they say that Windows SDK presupposes that structs are packed on 8-byte boundaries. So perhaps you could output the raw bytes and see if you detect a pattern. If that turns out to be the problem, try to change your compiler settings.

Are the methods in the <cstring> applicable for string class too?

I've tried out using memcpy() method to strings but was getting a "no matching function call" although it works perfectly when I use an array of char[].
Can someone explain why?
www.cplusplus.com/reference/cstring/memcpy/
std::string is an object, not a contiguous array of bytes (which is what memcpy expects). std::string is not char*; std::string contains char* (somewhere really deep).
Although you can pull out the std::string inner byte array by using &str[0] (see note), I strongly encourage you not to. Almost anything you need to do already is implemented as a std::string method. Including appending, subtracting, transforming and anything that makes sense with a text object.
So yes, you can do something as stupid as:
std::string str (100,0);
memcpy(&str[0],"hello world", 11);
but you shouldn't.
Even if you do need memcpy behaviuor, try to use std::copy instead.
Note: this is often done with C functions that expects some buffer, while the developer wants to maintain a RAII style in his code. So he or she produces std::string object but passes it as C string. But if you do clean C++ code you don't need to.
Because there's no matching function call. You're trying to use C library functions with C++ types.

How to transfer byte[] from C# to char buffer in C/ C++?

I have byte[] in C#. I want to pass this value to C++ (CLR). How to do it ?
I have tried converting the byte[][] to char[][] in C#.
Now Is it possible to use this char** variable in C++? If it is not, what I need to use ?
EDIT:
I want the output in character buffer in C++ code.
My Existing code can be found at Passing objects between C# library and C++ (CLR)

Compress array of data sent through sockets

We have a Server that sends some data to a client(both written using c++/MFC) using sockets
The data is getting a little too big and I'm looking for solutions to compress it. Basically I need to compress some char Arrays
I am not very familiar with MFC. I looked at zlib but I had a hard time getting anything compiling with my VS project. I am also able to use CLI (I tried using GZipStream and got it to work on C# but when I tried it on c++ I can't manage to get the CLI arrays to play nicely with the c++ char arrays)
Is zlib a mandatory requirement of your project ?
Otherwise, some other programs have simpler header file, which are easier to work with.
For example, this one (tested with GCC and MS's VS) :
int LZ4_compress (char* source, char* dest, int isize);
int LZ4_uncompress (char* source, char* dest, int osize);
Source code : http://code.google.com/p/lz4/
Take a look at http://zlib.net/
Also, there's a guy who did a wrapper around it (for convenience), might be worth checking it out: http://www.firstobject.com/easy-zlib-c++-xml-compression.htm
You can use any 3rd party compression library.
Also this question deals with a similar problem : c++ compress byte array
What error are you getting in trying to compile zlib.

How can I avoid encoding mixups of strings in a C/C++ API?

I'm working on implementing different APIs in C and C++ and wondered what techniques are available for avoiding that clients get the encoding wrong when receiving strings from the framework or passing them back. For instance, imagine a simple plugin API in C++ which customers can implement to influence translations. It might feature a function like this:
const char *getTranslatedWord( const char *englishWord );
Now, let's say that I'd like to enforce that all strings are passed as UTF-8. Of course I'd document this requirement, but I'd like the compiler to enforce the right encoding, maybe by using dedicated types. For instance, something like this:
class Word {
public:
static Word fromUtf8( const char *data ) { return Word( data ); }
const char *toUtf8() { return m_data; }
private:
Word( const char *data ) : m_data( data ) { }
const char *m_data;
};
I could now use this specialized type in the API:
Word getTranslatedWord( const Word &englishWord );
Unfortunately, it's easy to make this very inefficient. The Word class lacks proper copy constructors, assignment operators etc.. and I'd like to avoid unnecessary copying of data as much as possible. Also, I see the danger that Word gets extended with more and more utility functions (like length or fromLatin1 or substr etc.) and I'd rather not write Yet Another String Class. I just want a little container which avoids accidental encoding mixups.
I wonder whether anybody else has some experience with this and can share some useful techniques.
EDIT: In my particular case, the API is used on Windows and Linux using MSVC 6 - MSVC 10 on Windows and gcc 3 & 4 on Linux.
You could pass arround a std::pair instead of a char*:
struct utf8_tag_t{} utf8_tag;
std::pair<const char*,utf8_tag_t> getTranslatedWord(std::pair<const char*,utf8_tag_t> englishWord);
The generated machine code should be identical on a decent modern compiler that uses the empty base class optimization for std::pair.
I don't bother with this though. I'd just use char*s and document that the input has to be utf8. If the data could come from an untrusted source, you're going to have to check the encoding at runtime anyway.
I suggest that you use std::wstring.
Check out this other question for details .
The ICU project provides a Unicode support library for C++.