Is it possible to call a JNI C function inside another JNI C function? (directly or indirectly), or, a JNI function inside a normal C function?
For example:
int inverse_transform(double real[], double imag[], size_t n) {
return Java_com_example_ffttest_FFTActivity_transform(imag, real, n);
}
and inverse_transform() is later called inside another method.
JNIEXPORT jint JNICALL Java_com_example_ffttest_FFTActivity_convolve(...)
{
....
inverse_transform();
}
Does this work? I tried but it gives me errors about parameters and I don't know how to use *env and obj.
Certainly it's possible. Those are just functions with funny names as far as C is concerned.
One word of caution though - if the JNI function uses its JNIEnv parameter, you need to pass a valid one from a non-JNI function.
At the end JNI methods are normal c++ methods so offcourse you can do it .
Related
I have a dynamically linked ELF executable on Linux, and I want to swap a function in a library it is linked against. With LD_PRELOAD I can, of course, supply a small library with a replacement for the function that I compile myself. However, what if in the replacement I want to call the original library function? For example, the function may be srand(), and I want to hijack it with my own seed choice but otherwise let srand() do whatever it normally does.
If I were linking to make said executable, I would use the wrap option of the linker but here I only have the compiled binary.
One trivial solution I see is to cut and paste the source code for the original library function into the replacement - but I want to handle the more general case when the source is unavailable. Or, I could hex edit the needed extra code into the binary but that is specific to the binary and also time consuming. Is something more elegant possible than either of these? Such as some magic with the loader?
(Apologies if I were not using the terminology precisely...)
Here's an example of wrapping malloc:
// LD_PRELOAD will cause the process to call this instead of malloc(3)
// report malloc(size) calls
void *malloc(size_t size)
{
// on first call, get a function pointer for malloc(3)
static void *(*real_malloc)(size_t) = NULL;
static int malloc_signal = 0;
if(!real_malloc)
{
// real_malloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
*(void **) (&real_malloc) = dlsym(RTLD_NEXT, "malloc");
}
assert(real_malloc);
if (malloc_signal == 0)
{
char *string = getenv("MW_MALLOC_SIGNAL");
if (string != NULL)
{
malloc_signal = 1;
}
}
// call malloc(3)
void *retval = real_malloc(size);
fprintf(stderr, "MW! %f malloc size %zu, address %p\n", get_seconds(), size, retval);
if (malloc_signal == 1)
{
send_signal(SIGUSR1);
}
return retval;
}
The canonical answer is to use dlsym(RTLD_NEXT, ...).
From the man page:
RTLD_NEXT
Find the next occurrence of the desired symbol in the search
order after the current object. This allows one to provide a
wrapper around a function in another shared object, so that,
for example, the definition of a function in a preloaded
shared object (see LD_PRELOAD in ld.so(8)) can find and invoke
the "real" function provided in another shared object (or for
that matter, the "next" definition of the function in cases
where there are multiple layers of preloading).
See also this article.
Just for completeness, regarding editing the function name in the binary - I checked and it works but not without potential hiccups. E.g., in the example I mentioned, one can find the offset of "srand" (e.g., via strings -t x exefile | grep srand) and hex edit the string to "sran0". But names of symbols may be overlapping (to save space), so if the code also calls rand(), then there is only one "srand" string in the binary for both. After the change the unresolved references will then be to sran0 and ran0. Not a showstopper, of course, but something to keep in mind. The dlsym() solution is certainly more flexible.
I have an object of class AI, which has a private non static void function which has a lot of arguments: minmax(double& val,double alpha, double beta, unsigned short depth, board* thisTurn); because this is a very time intensive function I want to use a number of threads to run it concurrently, therefor I must create a thread with this function inside another function inside the AI class;
According toThis question to make threads inside member functions containing non static member functions wiht no arguments of said class, one must call:
std::thread t(&myclass::myfunc,this);
And according to this tutorial threads of fucntions with multiple arguments can be created as such:
std::thread t(foo,4,5)
where the function 'foo' has 2 integer arguments
However I desire to mix these to things, to call a function which has arguments, which is also a non static member function, from inside the class that it is a member of, and i am not sure how to mix these to things.
I have off course tried (remember that it is inside a function inside the AI class):
std::thread t(&AI::minmax,val,alpha,beta,depth,thisTurn,this);
and
std::thread t(&AI::minmax,this,val,alpha,beta,depth,thisTurn);
But both cases fails with a compile error like this:
error: no matching constructor for initialization of 'std::thread'
candidate constructor template not viable: requires single argument '__f', but
7 arguments were provided
My question is therefor, if or if not, it is even possiple to -- from inside a member function of a class -- call a non static member function which has several arguments as a thread, and if this is the case, how it is done.
This question is however not wether or not it is a good idea to use multithreading in my specific case.
Edit
After doing some testing i realized that i can not call functions with arguments as threads at all, not even non-member functions with only one argument called directly from main, this was however solved by asking this other question where i realized that i simply need to add the flag -std=c++11 (because apparantly macs don't always use all c++11 features as standard) after doing so the answer works fine.
You need to wrap references using std::ref. The following example compiles fine:
#include <iostream>
#include <thread>
class board;
class AI
{
public:
void minmax(double& val, double alpha, double beta, unsigned short depth, board* thisTurn)
{
std::cout << "minmax" << std::endl;
}
void spawnThread()
{
double val;
double alpha;
double beta;
unsigned short depth;
board* thisTurn;
std::thread t(&AI::minmax, this, std::ref(val), alpha, beta, depth, thisTurn);
t.join();
}
};
int main()
{
AI ai;
ai.spawnThread();
}
How do you cast a COM interface pointer to void pointer and then back to the COM pointer? Here is some code to illustrate my problem. It's very similar to this sample code: _com_ptr_t assignment in VC++
CoInitialize(NULL);
COMLib::ICalcPtr pCalc = COMLib::ICalcPtr("MyLibrary.Calculator");
pCalc->doSomething();
CoUninitialize();
return 0;
Now, if I were to cast the pCalc object to void*, how would I cast it back to COMLib::ICalcPtr? For example, the second line in the following code gives me a compile error 'QueryInterface' : is not a member of 'System::Void'. Obviously, it's trying to call IUknown.QueryInterface() on the object. Preferably I would like to do this without creating a new interface (hence, without implicitly calling QueryInterface and AddRef).
void *test = pCalc;
COMLib::ICalcPtr pCalc2 = test;//'QueryInterface' : is not a member of 'System::Void'
FYI, the reason I'm doing this is that the object is going to be passed around from java to jni VC++ code as a void* type. I'm open to any suggestion on what to do or what is going on behind the scene.
Same way you pass any other opaque structure that either doesn't fit in a pointer or doesn't convert easily: by passing its address.
void* test = new COMLib::ICalcPtr(pCalc);
...
COMLib::ICalcPtr pCalc2 = *(COMLib::ICalcPtr*)test;
delete (COMLib::ICalcPtr*)test;
This will result in calls to AddRef and Release, but not QueryInterface.
I have a vc++ dll in _cdecl calling convention. I want to use the exported function of that dll from the code in _stdcall calling convention. I m getting the linker error as expected. But how can i do that.
If you don't have sources to the stdcall DLL, You could load dynamically and specify the calling convention on the function pointer, otherwise project setting is used. Don't do this:
BOOL (*pBeep)(UINT) = 0; // defaults to project calling convention setting (/Gd etc)
If your project is set to __cdecl which is default, you'd actually want to explicitly set the function pointer to __stdcall:
BOOL (__stdcall *pBeep)(UINT) = 0;
make sure to cast correctly when assigning the function pointer as well:
pBeep = (BOOL (__stdcall *)(UINT))GetProcAddress(beepLibrary, "MessageBeep");
I have a vc++ dll which has a funciton call like this :
typedef void * SIS_HANDLE;
EXTERN_C SDK4OpenDevice (SIS_HANDLE* sDev );
Now am trying to call the VC++ dll in VB6 is there any equivalent for the same in VB6.
Thanks
Yes, it's a pointer-sized integer, which is Long in VB6. And your function takes a pointer to a pointer, so it will be ByRef.
Declare Sub SDK4OpenDevice(ByRef sDev As Long);
Watch out for the calling convention though, if that EXTERN_C macro doesn't hide a __stdcall or __pascal keyword, the function can't be called from VB6 directly.