want to pass a ArrayList<jsonobject> from cpp to java using jni - java-native-interface

actually i am new to jni and i wanted to know how to pass ArrayList" jsonObject " from cpp to java .i did not have an idea how to do it .Can some one help me writing the code.the jar used for this is json-simple 2.2.
this is my code tried only jsonobject to write
#include<jni.h>
#include<iostream>
#include<C:\Users\yuvaraj-pt3134\Desktop\User\User.h>
using namespace std;
JNIEXPORT jobject JNICALL Java_User_jo(JNIEnv *env, jclass cls,jobject obj)
{
jclass jsoncls = env->FindClass("org/json/JSONObject");
jobject newObj;
jmethodID constructorID = env->GetMethodID(jsoncls,"<init>","()V");
newObj = env->NewObject(jsoncls, constructorID);
jmethodID putStringID = env->GetMethodID(jsoncls, "put", "(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;");
if(putStringID == NULL)
{
printf("\n putStringID not created!\n");
return NULL;
}
jmethodID putIntID = env->GetMethodID(jsoncls, "put", "(Ljava/lang/String;I)Lorg/json/JSONObject;");
newObj = env->CallObjectMethod(newObj, putStringID, env->NewStringUTF("str"), env->NewStringUTF("Hai"));
newObj = env->CallObjectMethod(newObj, putIntID, env->NewStringUTF("val"), 7);
static jclass java_util_ArrayList;
static jmethodID java_util_ArrayList_;
jmethodID java_util_ArrayList_add;
java_util_ArrayList = env->FindClass("java/util/ArrayList");
java_util_ArrayList_ = env->GetMethodID(java_util_ArrayList, "<init>", "(I)V");
java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)Z");
jobject result=env->NewObject(java_util_ArrayList,java_util_ArrayList_,10);
result=env->CallObjectMethod(result, java_util_ArrayList_add, newObj);
return result;
}

ArrayList#add returns a boolean. You need to use CallBooleanMethod instead.
Don't forget to return newObj (your list) instead of result (the result of the add call)!

#include<jni.h>
#include<iostream>
#include<C:\Users\yuvaraj-pt3134\Desktop\User\User.h>
using namespace std;
JNIEXPORT jobject JNICALL Java_User_jo(JNIEnv *env, jclass cls,jobject obj)
{
jclass jsoncls = env->FindClass("org/json/JSONObject");
jobject newObj;
jmethodID constructorID = env->GetMethodID(jsoncls,"<init>","()V");
newObj = env->NewObject(jsoncls, constructorID);
jmethodID putStringID = env->GetMethodID(jsoncls, "put", "(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;");
if(putStringID == NULL)
{
printf("\n putStringID not created!\n");
return NULL;
}
jmethodID putIntID = env->GetMethodID(jsoncls, "put", "(Ljava/lang/String;I)Lorg/json/JSONObject;");
newObj = env->CallObjectMethod(newObj, putStringID, env->NewStringUTF("str"), env->NewStringUTF("Hai"));
newObj = env->CallObjectMethod(newObj, putIntID, env->NewStringUTF("val"), 7);
static jclass java_util_ArrayList;
static jmethodID java_util_ArrayList_;
jmethodID java_util_ArrayList_add;
java_util_ArrayList = env->FindClass("java/util/ArrayList");
java_util_ArrayList_ = env->GetMethodID(java_util_ArrayList, "<init>", "()V");
java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)Z");
jobject result=env->NewObject(java_util_ArrayList,java_util_ArrayList_,10);
env->CallBooleanMethod(result, java_util_ArrayList_add, newObj);
newObj = env->NewObject(jsoncls, constructorID);
newObj = env->CallObjectMethod(newObj, putStringID, env->NewStringUTF("str"), env->NewStringUTF("yuvaraj"));
newObj = env->CallObjectMethod(newObj, putIntID, env->NewStringUTF("val"), 9);
env->CallBooleanMethod(result, java_util_ArrayList_add, newObj);
return result;
}

Related

Pass a class as argument to a NSThread

How can I pass a class as argument to a thread using NSThread. In windows I was doing something like:
DWORD WINAPI threadFunc(LPVOID mpThis) {
MYCLSS *pThis = reinterpret_cast<MYCLSS*>(mpThis);
....
void MYCLSS::func() {
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadFunc, (void*)this, 0, NULL);
....
For Mac I have not found any examples of this kind. Please help me
I found the solution, it can be like windows
class CLS_CPP {
public:
void Func();
void Check();
int var_check;
};
#interface CLS_OSX : NSObject {
#public
void *obj;
}
-(void)osx_thread;
#end
#implementation CLS_OSX
-(void)osx_thread {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CLS_CPP *pThis = reinterpret_cast<CLS_CPP*>(obj);
pThis->Check();
NSLog(#"Check var %d", pThis->var_check);
[NSThread exit];
[pool drain];
}
#end
void CLS_CPP::Func() {
var_check=77;
CLS_OSX *trgt=[[CLS_OSX alloc] init];
trgt->obj=(void*)this;
[NSThread detachNewThreadSelector:#selector(osx_thread) toTarget:trgt withObject:trgt];
}
void CLS_CPP::Check() {
NSLog(#"CLS_CPP::Check success");
}
int main(int argc, char ** argv) {
CLS_CPP oAPP;
oAPP.Func();
}

Proper transition between audio tracks using Superpowered Audio Kit

I implemented the audio playback successfully but a frequent problem comes up where a sharp auditory glitch occurs when "next song" is clicked from JAVA. This sound glitch elapses approx. around 100ms. And occurs more frequently before the next song starts playing.
Please importantly note this:
I call "delete" on every variable class and "free" stereobuffers (setdestroyallthreads) at the end of every playback, then "process"(process) method before every playback starts.
From Java, the transition sequence looks like this;
PlayerClass.setDestroyAllThreads( );
PlayerClass.open("new_path", sampleRate, bufferSize );
PlayerClass.play( );
Here is my snippet;
static void playerEventCallbackA(void *clientData, SuperpoweredAdvancedAudioPlayerEvent event, void * __unused value) {
if (event == SuperpoweredAdvancedAudioPlayerEvent_LoadSuccess) {
SuperpoweredAdvancedAudioPlayer *player = *((SuperpoweredAdvancedAudioPlayer **)clientData);
}else if (event == SuperpoweredAdvancedAudioPlayerEvent_EOF) {
playerBass->pause();
playerB->pause();
finishedPlaying = true;
}else if (event == SuperpoweredAdvancedAudioPlayerEvent_LoadError) {
};
}
static bool audioProcessing(void *clientdata, short int *audioIO, int numberOfSamples, int __unused samplerate) {
return ((Eve *)clientdata)->process(audioIO, (unsigned int)numberOfSamples);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
Eve::Eve(const char *path,unsigned int samplerate,unsigned int buffersize) : activeFx(0), crossValue(0.0f), volBass(1.0f * headroom), volB(1.0f * headroom) {
stereoBuffer = (float *)memalign(16,(buffersize + 16) * sizeof(float) * 2);
playerBass = new SuperpoweredAdvancedAudioPlayer(&playerBass , playerEventCallbackA, samplerate, 0);
playerB = new SuperpoweredAdvancedAudioPlayer(&playerB, playerEventCallbackB, samplerate, 0);
filterb = new SuperpoweredFilter(SuperpoweredFilter_Resonant_Lowpass, samplerate*0.98);
spatializer = new SuperpoweredSpatializer(samplerate);
playerBass->open(path);
playerB->open(path);
finishedPlaying = false;
playerBass->syncMode = playerB->syncMode = SuperpoweredAdvancedAudioPlayerSyncMode_TempoAndBeat;
audioSystem = new SuperpoweredAndroidAudioIO(samplerate, buffersize, false, true, audioProcessing, this, -1, SL_ANDROID_STREAM_MEDIA, buffersize * 2);
}
Eve::~Eve() {
delete playerBass;
delete playerB;
delete spatializer;
delete filterb;
delete audioSystem;
finishedPlaying = false, playingNow = false, pausedNow = false, processed = false, hd = false;
}
void Eve::onPlay() {
playerBass->play(false);
playerB->play(false);
playingNow = true;
}
void Eve::setBassValue(int bass) {
filterb->setResonantParameters(floatToFrequency(0.2f),ebass);
filterb->enable(true);
}
void Eve::setDestroyAllThreads(){
delete playerBass;
delete playerB;
delete spatializer;
delete filterb;
delete audioSystem;
finishedPlaying = false, playingNow = false, pausedNow = false, processed = false, hd = false;
}
bool Eve::process(short int *output, unsigned int numberOfSamples) {
bool masterIsA = (crossValue <= 0.5f);
double masterBpm = masterIsA ? playerBass->currentBpm : playerB->currentBpm;
double msElapsedSinceLastBeatA = playerBass->msElapsedSinceLastBeat;
bool silence = !playerBass->process(stereoBuffer, false, numberOfSamples*1, volBass, masterBpm, playerB->msElapsedSinceLastBeat);
processed = true;
filterb->process(stereoBuffer, stereoBuffer, numberOfSamples);
if (playerB->process(stereoBuffer, !silence, numberOfSamples, volB, masterBpm, msElapsedSinceLastBeatA)) silence = false;
spatializer->process(stereoBuffer, stereoBuffer, (float*)output, (float*)output, numberOfSamples, true);
SuperpoweredFloatToShortInt(stereoBuffer, output, numberOfSamples);
return !silence;
}
static Eve *eve = NULL;
extern "C" JNIEXPORT void Java_com_EvePlayer_Eve(JNIEnv *javaEnvironment, jobject self, jstring songPath, jint samplerate, jint buffersize) {
const char *path = javaEnvironment->GetStringUTFChars(songPath, JNI_FALSE);
eve = new Eve(path,(unsigned int)samplerate,(unsigned int)buffersize);
javaEnvironment->ReleaseStringUTFChars(songPath, path);
}
extern "C" JNIEXPORT void Java_com_EvePlayer_SetTempFolder(JNIEnv *javaEnvironment, jobject __unused obj, jstring path) {
const char *str = javaEnvironment->GetStringUTFChars(path, 0);
SuperpoweredAdvancedAudioPlayer::setTempFolder(str);
javaEnvironment->ReleaseStringUTFChars(path, str);
}
extern "C" JNIEXPORT void Java_com_EvePlayer_evePlay(JNIEnv *javaEnvironment, jobject self){
eve->onPlay();
}
extern "C" JNIEXPORT void Java_com_EvePlayer_setDestroyAllThreads(JNIEnv *javaEnvironment, jobject self) {
eve->setDestroyAllThreads();
}
Destroy the audio I/O ("audioSystem" in your code) first. The audio I/O invokes your audio processing callback periodically, so it needs to be destroyed first, it will use deleted objects otherwise.

Using C, how to pass a string to the Smoke C++ API

Smoke provides an introspective C++ API wrapper to the Qt framework.
https://techbase.kde.org/Development/Languages/Smoke
https://techbase.kde.org/Development/Languages/Smoke/API_Documentation
SmokeC wraps the the Smoke wrapper with C functions to facilitate using the Smoke API from C.
https://github.com/pankajp/pysmoke/blob/master/smokec/smokec.cpp
Working example application in C (functionally identical to the C++ example in the first link above):
https://github.com/pankajp/pysmoke/blob/master/examples/hellowidget.c
I'm trying to modify this example application and add further calls to QWidget object methods, but I can't figure out how to call a method that takes a QString argument, such as setWindowTitle, whose signature is
void setWindowTitle(const QString &);
Here's my best guess:
/* Set the window title... Segfaults */
methId = Smoke_findMethod(classId.smoke, "QWidget", "setWindowTitle$");
klass = Smoke_classes(classId.smoke)[classId.index];
meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
stack[1].s_voidp = (void*)"hello universe";
(*klass.classFn)(meth.method, widget, stack);
... but this segfaults. Can anyone advise how I should construct a QString argument using the SmokeC wrapper?
My complete modified example application follows.
/*
* File: hellowidget.c
* Author: pankaj
*
* Created on November 19, 2013, 2:41 PM
*/
#include <stdio.h>
#include <string.h>
#include "smokec.h"
#include "bindings.h"
/*
* In a bindings runtime, this should return the classname as used
* in the bindings language, e.g. Qt::Widget in Ruby or
* Qyoto.QWidget in C# or QtGui.QWidget in python
*/
char *className(CSmokeBinding binding, Index classId) {
return (char*) Smoke_classes(CSmoke_FromBinding(binding))[classId].className;
}
void deleted(CSmokeBinding binding, Index classId, void *obj)
{
}
cbool callMethod(CSmokeBinding binding, Index method, void *obj, Stack args, cbool isAbstract)
{
return 0;
}
int main(int argc, char **argv)
{
/* Initialize the Qt SMOKE runtime. */
init_qtcore_CSmoke();
init_qtgui_CSmoke();
CSmoke qtcore_smoke = qtcore_CSmoke();
CSmoke qtgui_smoke = qtgui_CSmoke();
/* Create a SmokeBinding for the Qt SMOKE runtime. */
CSmokeBinding qtcoreBinding = SmokeBinding_new(qtcore_smoke, deleted, callMethod, className);
CSmokeBinding qtguiBinding = SmokeBinding_new(qtgui_smoke, deleted, callMethod, className);
/* Find the 'QApplication' class. */
CModuleIndex classId = findClass("QApplication");
/* find the methodId. we use a munged method signature, where
* $ is a plain scalar
* # is an object
* ? is a non-scalar (reference to array or hash, undef) */
CModuleIndex methId = Smoke_findMethod(classId.smoke, "QApplication", "QApplication$?"); // find the constructor
/* Get the Smoke::Class */
Class klass = Smoke_classes(classId.smoke)[classId.index];
// findMethod() returns an index into methodMaps, which has
// information about the classId, methodNameId and methodId. we
// are interested in the methodId to get a Smoke::Method
Method meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
StackItem stack[3];
// QApplication expects a reference to argc, so we pass it as a pointer
stack[1].s_voidp = &argc;
stack[2].s_voidp = argv;
// call the constructor, Smoke::Method::method is the methodId
// specifically for this class.
(*klass.classFn)(meth.method, 0, stack);
// the zeroth element contains the return value, in this case the
// QApplication instance
void *qapp = stack[0].s_voidp;
// method index 0 is always "set smoke binding" - needed for
// virtual method callbacks etc.
stack[1].s_voidp = qtguiBinding.binding;
(*klass.classFn)(0, qapp, stack);
// create a widget
classId = findClass("QWidget");
methId = Smoke_findMethod(classId.smoke, "QWidget", "QWidget");
klass = Smoke_classes(classId.smoke)[classId.index];
meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
(*klass.classFn)(meth.method, 0, stack);
void *widget = stack[0].s_voidp;
// set the smoke binding
stack[1].s_voidp = qtguiBinding.binding;
(*klass.classFn)(0, widget, stack);
/* Show the widget maximized.*/
methId = Smoke_findMethod(classId.smoke, "QWidget", "showMaximized");
meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
(*klass.classFn)(meth.method, widget, 0);
/* Raise the window to the foreground */
methId = Smoke_findMethod(classId.smoke, "QWidget", "raise");
meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
(*klass.classFn)(meth.method, widget, 0);
/* Set the modified indicator. */
methId = Smoke_findMethod(classId.smoke, "QWidget", "setWindowModified$");
meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
stack[1].s_bool = 1;
(*klass.classFn)(meth.method, widget, stack);
/* Set the window title... Segfaults */
methId = Smoke_findMethod(classId.smoke, "QWidget", "setWindowTitle$");
klass = Smoke_classes(classId.smoke)[classId.index];
meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
stack[1].s_voidp = (void*)"hello universe";
(*klass.classFn)(meth.method, widget, stack);
// we don't even need findClass() when we use the classId provided
// by the MethodMap
methId = Smoke_findMethod(qtgui_smoke, "QApplication", "exec");
klass = Smoke_classes(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].classId];
meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
// call QApplication::exec()
(*klass.classFn)(meth.method, 0, stack);
// store the return value of QApplication::exec()
int retval = stack[0].s_int;
// destroy the QApplication instance
methId = Smoke_findMethod(qtgui_smoke, "QApplication", "~QApplication");
meth = Smoke_methods(methId.smoke)[Smoke_methodMaps(methId.smoke)[methId.index].method];
(*klass.classFn)(meth.method, qapp, 0);
// destroy the smoke instance
CSmoke_delete(qtgui_smoke);
CSmoke_delete(qtcore_smoke);
// return the previously stored value
return retval;
}

Sending C++ class object through the NSNotificationCenter in Box2d. Error: No viable conversion from 'MyContact' to 'id'

I try to implement Contact Listener in box2d *cocos2d*. And I want integrate NSNotificationCenter in PostSolve function, but when I try to point the object: parametr I've got the error:
No viable conversion from 'MyContact' to 'id'
How can I send MyContact object through the NSNotificationCenter?
MyContactListener class
//
// MyContactListener.m
// Box2DPong
//
// Created by Ray Wenderlich on 2/18/10.
// Copyright 2010 Ray Wenderlich. All rights reserved.
//
#import "MyContactListener.h"
#import "ConfigMacro.h"
MyContactListener::MyContactListener() : _contacts(),_contactsObjects(){}
MyContactListener::~MyContactListener() {}
void MyContactListener::BeginContact(b2Contact* contact) {
b2Body *bodyA = contact->GetFixtureA()->GetBody();
b2Body *bodyB = contact->GetFixtureB()->GetBody();
if(bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL)
{
MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB() };
_contacts.push_back(myContact);
}
}
void MyContactListener::EndContact(b2Contact* contact) {
MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB() };
std::vector<MyContact>::iterator pos;
pos = std::find(_contacts.begin(), _contacts.end(), myContact);
if (pos != _contacts.end()) {
_contacts.erase(pos);
}
}
void MyContactListener::PreSolve(b2Contact* contact, const b2Manifold* oldManifold) {}
void MyContactListener::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) {
b2Body *bodyA = contact->GetFixtureA()->GetBody();
b2Body *bodyB = contact->GetFixtureB()->GetBody();
if(bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL)
{
int32 count = contact->GetManifold()->pointCount;
float32 maxImpulse = 0.0f;
b2Vec2 collision;
for (int32 i = 0; i < count; ++i) {
maxImpulse = b2Max(maxImpulse, impulse->normalImpulses[i]);
if (i == 0) {
b2WorldManifold worldManifold;
contact->GetWorldManifold(&worldManifold);
collision = worldManifold.points[0];
}
}
MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB(), maxImpulse, collision };
[[NSNotificationCenter defaultCenter] postNotificationName:kReceivedImpulse object:myContact userInfo:nil];
}
}
The object: argument should be a pointer to an Objective-C object - you're trying to pass what looks like a struct.

show hello world swing with jni

This is my main.cpp code:
#include <jni.h>
#include <QDebug>
int main(int argc, char *argv[]) {
JavaVM *jvm;
JNIEnv *env;
jstring jstr;
jobjectArray args;
jclass stringClass;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.classpath=.";
options[2].optionString = "";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 3;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (res < 0) {
qDebug()<<"Can't create Java VM\n";
exit(1);
};
jclass cls = env->FindClass("HelloWorldSwing");
if (cls == 0) qDebug()<<"Sorry, I can't find the class";
jmethodID get_main_id =
env->GetStaticMethodID(cls,"main","([Ljava/lang/String;)V");
jstr=env->NewStringUTF("hola que tal");
stringClass=env->FindClass("java/lang/String");
args=env->NewObjectArray(1,stringClass,jstr);
env->CallStaticVoidMethod(cls,get_main_id,args);
jvm->DestroyJavaVM();
qDebug()<<"Java VM destroy\n";
}//end main.
HelloWorldSwing is a class that show a jframe with "Hello world" text, but don't show nothing, if i write system.out.println("hello world")in the java class, function correctly.
You're destroying the VM before it has a chance to display the UI.
The call to System.out.println is synchronous, so it happens before you destroy the VM.
Creating a UI involves creating and dispatching events on a separate thread. If you were to simply pause for several seconds before destroying the VM, I think you'd see your UI show up.
The problem was in the main class of java.
JNI calls the main method and when this end, the program end. I just put a guithread.join (); in the main method and all run correctly.