JNI methods with more than one argument? - java-native-interface

I am new to JNI and I wanted to pass three integer to the below function
void pauseEffectJNI(unsigned int nSoundId)
{
// void pauseEffect(int)
JniMethodInfo methodInfo;
if (! getStaticMethodInfo(methodInfo, "pauseEffect", "(I)V"))
{
return ;
}
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)nSoundId);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
Please correct me if I am wrong
What will come in this line
if (! getStaticMethodInfo(methodInfo, "pauseEffect", "(I)V"))
(I;I;I)V or just (III)V
if my functions is void pauseEffectJNI(unsigned int nSoundId, unsigned int number1, unsigned int number2) ??
Basically I want to know what if I want to pass more than one Integer
Thanks for the help ... Here is function I made ...COrrect me if i m wrong
void pauseEffectJNI(unsigned int nSoundId , unsigned int number)
{
// void pauseEffect(int)
JniMethodInfo methodInfo;
if (! getStaticMethodInfo(methodInfo, "pauseEffect", "(III)V"))
{
return ;
}
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)nSoundId,(int) number);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}

Don't try to figure out JNI method signatures by hand, when 'javap -s' will tell you the correct answer with 100% reliability. Use the tools.

Related

array of pointer to functions c++

Can someone tell me what is wrong with this code?!
visual studio tells the operand of * must be a pointer...
(in line that we call operation)...
can someone tell how exactly declaring an array of pointer to functions is?
I'm really confused.
#include<iostream>
#include<conio.h>
using namespace std;
int power(int x)
{
return(x*x);
}
int factorial(int x)
{
int fact=1;
while(x!=0)
fact*=x--;
return fact;
}
int multiply(int x)
{
return(x*2);
}
int log(int x)
{
int result=1;
while(x/2)
result++;
return result;
}
//The global array of pointer to functions
int(*choice_array[])(int)={power,factorial,multiply,log};
int operation(int x,int(*functocall)(int))
{
int res;
res=(*functocall)(x);
return res;
}
int main()
{
int choice,number;
cout<<"Please enter your choice : ";
cin>>choice;
cout<<"\nPlease enter your number : ";
cin>>number;
cout<<"\nThe result is :"<<operation(number,(*choice_array[choice](number)));
}
This call
operation(number, (*choice_array[choice](number)))
is invalid.
You have to supply a pointer to a function as second argument. Either write
operation(number, choice_array[choice] )
or
operation(number, *choice_array[choice] )
The problem is that (*choice_array[choice](number)) isn't a function itself but a result of function call.
Did you mean (*choice_array[choice])?
operation takes a function as argument, but (*choice_array[choice](number)) is an int, cuz it's applying choice-array[choice] to number
just do operation(number, choice_array[choice])
EDIT : don't want to say something wrong, but it seems to me that
*(choice_array[choice])
(choice_array[choice])
are the same, (meaning pointer to the function IS (can be used as a call to) the function, and you cant "dereference" it)

Callback functions with different arguments

I have two functions with a little different functionality, so I can't make them as template functions.
int func64(__int64 a) {
return (int) a/2;
}
int func32(int a) {
return a--;
}
Depending on variable b64, I would like to call func64 or func32. I don't want check if b64 is true many times in my code, so I use pointers to functions.
void do_func(bool b64) {
typedef int (*pfunc32)(int);
typedef int (*pfunc64)(__int64);
pfunc32 call_func;
if (b64)
call_func = func64; //error C2440: '=' : cannot convert from 'int (__cdecl *)(__int64)' to 'pfunc32'
else
call_func = func32;
//...
call_func(6);
}
How can I avoid this error and cast call_func to pfunc32 or pfunc64?
The language requires all functions called through the same function pointer to have the same prototype.
Depending on what you want to achieve, you could use the pointer/cast aproach already mentioned (which satisfies this requirement at the loss of type safety) or pass a union instead:
union u32_64
{
__int64 i64;
int i32;
};
int func64(union u32_64 a) {
return (int) a.i64/2;
}
int func32(union u32_64 a) {
return --a.i32;
}
void do_func(bool b64) {
typedef int (*pfunc)(union u32_64);
pfunc call_func;
if (b64)
call_func = func64;
else
call_func = func32;
//...
union u32_64 u = { .i64 = 6 };
call_func(u);
}
Pass a void pointer and cast it in the function body.
Of course this means less compiler control if you use the wrong type; if you call func64 and pass an int to it the program will compile and produce wrong results without giving you any tip of what is going wrong.
int func64(void *a) {
__int64 b = *((__int64*) a);
return (int) b/2;
}
int func32(void *a) {
int b = *((int *) a)
return b-1;
}
I need to call func32() or func64() depending on flag b64
So do that:
void do_func(bool b64) {
if (b64)
func64(6);
else
func32(6);
}
Well, first of all, please note that function func32 is returning the input argument as is.
This is because with return a--, you are returning the value of a before decrementing it.
Perhaps you meant to return a-1 instead?
In any case, you can simply declare this function as int func32(__int64 a).
This way, it will have the same prototype as function func64, but will work exactly as before.
BTW, calling a function through a pointer might be more "expensive" than a simple branch operation, so depending on your application, you might be better off with a simple if/else conditional statement...
Make a wrapper for func64:
int func64_as_32(int a) {
return func64(a);
}
Now you can assign either func32 or func64_as_32 to call_func since they have the same signature. The value you pass in, 6, has type int so passing it to func64_as_32 has the same effect as passing it directly to func64.
If you have call sites where you pass in a value of type __int64 then you'd do it the other way around, wrap func32.
As bool in C++ converts to int ( true => 1, false => 0 ) you can use b64 as array index. So take SJuan76's advice, convert your functions prototype to int f(void*) and put them into array int (*array_fun[2])(void* x); . You can call these functions then like that :
int p = 6;
array_fun[b64](&p);

Accessing a passed array of structures in C++

I'm learning C++ by reading forums and books so I'm kind of new to the programmer's world.
So please don't hesitate to improve my code because I'm eager to learn !
I'm having a problem to access an array of structure that I passed to a function.
Here's my code :
struct Comber
{ double real;
double im;
double mod;
};
int main (void)
{
struct Comber *Nmbr=NULL; //Nmbr Initialised for passing to Read where it's re-declared
int N;
Read(Nmbr, N);
Module(Nmbr, N);
}
void Read (Comber *Nmbr, int &N)
{
cout<<"\nHow many of those numbers do you have ?\t";
cin>>N;
Nmbr = new struct Comber [N];
for(int i=0;i<=N;i++)
{
cout<<"#"<<i<<"\nreal :\t";
cin>>Nmbr[i].real;
cout<<"img :\t";
cin>>Nmbr[i].im;
cout<<"-----"<<endl;
}
}
void Module (Comber *Nmbr, const int &N)
{
for(int i=0;i<N;i++)
{
//Here's where my problem is at.
Nmbr[i].mod=sqrt(pow(Nmbr[i].real,2)+pow(Nmbr[i].im,2));
}
}
I get an access violation because there's either no data stored or I'm looking at the wrong place. (right ?)
So I'm wondering whether the mistake is in Read or in Module and what actually is.
Thanks for looking into it !
If you want to change the value of the Nmbr pointer, you need to pass it by reference or pointer, not by value. Like this:
void Read (Comber *&Nmbr, int *N)
With your code Nmbr in the main is not chaged.

How to use tinycthread to do C++ concurrent programming

I just started use tinycthread.h to do my concurrent programming. However, i got no ideas how to use it. Currently, i want to know how can I create a thread function with this library.
Here are two functions listed in the tinycthread library
typedef int(* thrd_start_t)(void *arg)
int thrd_create (thrd_t * thr,thrd_start_t func,void * arg )
I want to create a thread function with an integer as a parameter.
int Haha (int a){} -> to be my thread function
int main(){
thrd_t t;
thrd_create(&t,Haha,int a);
}
I write something like this in my program.
but as the accepted typedef int(* thrd_start_t)(void *arg) of a typedef is in this way which does not allow me to put any integer as my parameters. So what should i do to create a thread function with an integer as a parameter.
The argument of Haha must be void * not int, so try to pass your integer inputs by some casting:
int Haha (void *arg)
{
int *a = static_cast<int*>(arg);
printf("%d", *a);
return 0;
}
int main()
{
int param = 123;
thrd_t t;
thrd_create(&t, Haha, &param);
thrd_join(t, NULL);
}
Since TinyCThread is C alternative of TinyThread++, You should use that C++ class library.
Also, C++ supports std::thread take a look at it.
Pass a pointer to an int variable holding the value you want to pass:
int a = 10;
thrd_create(&t, Haha, &a);
...
int Haha(void *ptr) {
int *ap = static_cast<int*>(ptr);
int a = *ap;
}
If you intend to write through the ap pointer, make sure the pointed at object didn't go out of scope.

Max-heap implementation

Following code for max-heap implementation
#include<iostream>
#include<math.h>
using namespace std;
#define maxn 1000
int x[maxn];
int parent(int i){
return int(i/2);
}
int left(int i){
return 2*i;
}
int right(int i){
return 2*i+1;
}
void max_heap(int x[],int i,int size){
int largest;
int l=left(i);
int r=right(i);
if (l<=size && x[l]>x[i]){
largest=l;
}
else
{
largest=i;
}
if (r<=size && x[r]>x[largest]){
largest=r;
}
if (largest!=i) { int s=x[i];x[i]=x[largest];x[largest]=s;}
max_heap(x,largest,size);
}
int main(){
x[1]=16;
x[2]=4;
x[3]=10;
x[4]=14;
x[5]=7;
x[6]=9;
x[7]=3;
x[8]=2;
x[9]=8;
x[10]=1;
int size=10;
max_heap(x,2,size);
for (int i=1;i<=10;i++)
cout<<x[i]<<" ";
return 0;
}
When I run it, it writes such kind of warning:
1>c:\users\datuashvili\documents\visual studio 2010\projects\heap_property\heap_property\heap_property.cpp(36): warning C4717: 'max_heap' : recursive on all control paths, function will cause runtime stack overflow
Please tell me what is wrong?
The message tells you exactly what's wrong. You haven't implemented any checks to stop the recursion. One smart compiler.
max_heap function doesn't have base case, i.e., a return statement. You are just recursively calling the function but never saying when to break another successive call to the max_heap.
Also, in your example you are just calling the function with out satisfying any condition. Usually recursion is done or not done when a case is satisfied.
please tell me what is wrong?
Another problem that I see is that the size of your array x is 10. But the indices that you are using to set values are 1-10.
Put
max_heap(x,largest,size);
inside last check, like this:
if (largest!=i)
{
int s=x[i];
x[i]=x[largest];
x[largest]=s;
max_heap(x,largest,size);
}
and you're done!
There are many other problems with your code, but to answer your specific question, above change would do!