Calling DeleteObjectRef when GetObjectField returns jstring - java-native-interface

When calling GetObjectField which returns a jstring, do I need to call DeleteLocalRef for the jstring?
I know I have to do it for returned objects, but I have no clue for jstrings.

Related

How to properly call a thiscall function with this being an mfc control

So i have an injected DLL and i'm trying to call a thiscall function with the following signature:
int __thiscall sub_76FDF3(CMFCTabCtrl *this, int, int)
From what i've read i can create a function pointer and call it directly, so i've created a typedef for the function:
#include <afxtabctrl.h>
typedef int(__thiscall *TestFuncDef)(CMFCTabCtrl, int, int);
TestFunc = (TestFuncDef)0x76FDF3;
Now i'm scratching my head wondering if i have to locate 'this' being the real tabctrl and then somehow cast it to a CMFCTabCtrl to be able to actually call the function passing my own int params?
New to all this so i apologize if it's a daft question. Thanks.
Your code is correct for calling a _thiscall function, by defining your function pointer as a __thiscall and passing the this pointer as the first argument, it will correctly put it in ECX and everything should work fine as long as the this pointer points to a valid object of the correct type.
You will need to find an object in memory and pass it's address as the this pointer. If you can't find the correct object then you can try to find the correct constructor, call the constructor and pass the return as your this pointer.
To find the constructor, reverse engineer the other virtual table functions for that class and try to find lines of code that look like it's initializing member variables.
If you want to find real objects, you can hook the vtable functions and make a copy of the this pointer, essentially creating a list of objects of that type. You can then try using these.
You can also just create a struct of about the correct size and just pass that as the this pointer and see what happens, just make sure the vtable pointer points to the correct vtable so those functions resolve correctly. Sometimes this works fine if it's not dependent on the member variable having proper values.

jni deleteRef for jclass and jobject

is this right way of deleteing reference for jclass and jobject
JNIEXPORT void JNICALL Java_method(JNIEnv *env,jobject, jobject objArray)
{
int n = env->GetArrayLength(objArray);
for (int i = 0; i<n ; ++i)
{
jobject sObject = env->GetObjectArrayElement(objArray, i);
jclass sObjectClass = env->GetObjectClass(sObject);
dosomething(sObjectClass, sObject);
env->DeleteLocalRef(sObject);
env->DeleteLocalRef(sObjectClass);
}
Short answer:
Yes it is a right way. The call DeleteLocalRef is not necessary but it is useful if the objArray is big or if the function execution time is long.
Longer answer:
Oracle reference documentation states
Primitive types, such as integers, characters, and so on, are copied
between Java and native code. Arbitrary Java objects, on the other
hand, are passed by reference. The VM must keep track of all objects
that have been passed to the native code, so that these objects are
not freed by the garbage collector. The native code, in turn, must
have a way to inform the VM that it no longer needs the objects. In
addition, the garbage collector must be able to move an object
referred to by the native code.
So any object that native code use must be marked as eligible for garbage collection from native code point of view when native code does need the object anymore. JNI has two types of references - global and local references. The references retrieved from GetObjectArrayElement and GetObjectClass are local because:
All Java objects returned by JNI functions are local references.
VM automatically frees all local references when a native function returns. So it is not necessary to free these references by DeleteLocalRef in most cases because VM frees them automatically.
But if there are a lot of local references required in one function call or the call takes long time then it is worth to free them explicitly immediately when they are not needed and do not wait to function returns. Freeing helps VM to do better memory management.

why "boost.thread" call "intrusive_ptr_add_ref" manually?

In boost.thread's start function, the source code is something like that:
bool thread::start_thread_noexcept()
{
uintptr_t const new_thread = _beginthreadex(
0,
0,
&thread_start_function,
thread_info.get(),
CREATE_SUSPENDED,
&thread_info->id);
if (!new_thread)
{
return false;
}
// why call this line?
intrusive_ptr_add_ref(thread_info.get());
thread_info->thread_handle = (detail::win32::handle)(new_thread);
ResumeThread(thread_info->thread_handle);
return true;
}
thread_info is a intrusive smart pointer which points to the thread information data, before calling the intrusive_ptr_add_ref, the count is already 1, I don't know why call the intrusive_ptr_add_ref mannually here. I think Intrusive smart pointer's job should be calling the intrusive_ptr_add_ref and intrusive_ptr_release automatically.
I've tried to step through the source code but didn't find any clue.
Can anyone tell me
1. why call intrusive_ptr_add_ref manually here?
2. In what condition when using the intrusive_ptr, I should call intrusive_ptr_add_ref manually?
Thanks, Sincerely.
why call intrusive_ptr_add_ref manually here?
To represent the sharing of ownership of the pointer.
_beginthreadex was passed thread_info.get() as a parameter. This parameter will be passed to thread_start_function when the thread starts. And this function expects the pointer to remain valid until that happens.
Now, _beginthreadex is a simple function. It's not a variadic template that can take arbitrary parameters or anything. It takes exactly and only a naked pointer, and passes exactly that to the start function.
It is very possible for the person creating the boost::thread to call thread::detach before thread_start_function ever gets called. And if that happened, then the thread_info intrusive pointer would be destroyed, thus causing the destruction of its contained object.
And that leaves _beginthreadex with a destroyed pointer. That's bad.
What _beginthreadex needs to do is claim ownership of the intrusvie pointer. But since the API doesn't take a boost::intrusive_ptr, how do you do that?
By bumping the reference count. The reference count increase is how _beginthreadex claims ownership of the object.

How do I pass a LPCSTR to a c++ function convert to string and return a LPCSTR?

I have a C++ API function that is called by Install Shield via InstallScript:
SQLHELPER_API LPCSTR GetAvailableAppName(LPCSTR appNameP)
{
//return "this works just fine";
std::string newAppName = "I work, maybe?";
LPCSTR returnVal = newAppName.c_str();
return returnVal;
}
The only thing that returns is an empty string. If I just return passed in variable "appNameP" it returns that just fine as well.
My main issue is that I need to pass in a LPCSTR and perform some string operation on it.
A LPCSTR is the same as const char *.
Passing a C-style string like that to a function call is fine.
Returning a pointer to a local function variable is not fine, because this local variable doesn´t exist anymore after the function ends. As soon as you´re using the pointer in main (or whereever the function was called), it points to a memory which doesn´t belong to you anymore, and the value may have changed already.
There are several possibilites, each with a downside:
Using only memory you got as parameter (eg. appNameP, because this has to be something from outside and will still exist after the function ends). Downside: You need to pass something fitting for that purpose => the function signature or at least the requirements for the parameters changes, and you´ve to check/change how it is called.
Allocating something with new. Downside: Somewhere later, outside, delete[] have to be called.
Returning something like std::string. Downside: As in #1, the function signature changes, and you´ve to change how it is called.
If InstallShield calls this function itself:
What InstallShield expects you to do should be somewhere in the documentation.

Who takes ownership of the IErrorInfo?

We use Native COM support in our code havily. Everything's fine except that we don't like the fact that on error _com_raise_error() is called which throws a _com_error exception. Since we have our own hierarchy of exceptions catching this _com_error is inconvenient - it's not in our hierarchy and even doesn't inherit from std::exception.
So we need to override the _com_raise_error(). It's easy by itself - just define it in our code, the linker will link with it.
However is unclear who owns the IErrorInfo. The signature is
void __stdcall _com_raise_error( HRESULT hr, IErrorInfo* info );
So whoever calls the function would be responsible for calling IErrorInfo::Release() after the function returns. But how would the function return at all if we throw an exception in it and the control would transfer somewhere else?
I checked - called AddRef(), then Release() immediately upon entry into that function - the reference counter is 1. Later we pass ownership to the constructed exception object - it calls AddRef() in its constructor and Release() in destructor. I suppose this is incorrect since the AddRef() will increase the reference count to 2 but then only one Release() will be called (in the exception destructor).
Am I correct that the AddRef() in the constructor will cause a memory leak or is there some internal mechanism that doesn't allow IErrorInfo objects to leak at all?
_com_raise_error() is not meant to return. It must raise an exception, regardless of its type. If you look at the default implementation of _com_raise_error(), the raised _com_error object takes ownership of the specified IErrorInfo object. _com_error's constructor has an fAddRef parameter that has a default value of false, so AddRef() is not called. Release() is then called when the _com_error object is destructed by whatever exception handler catches it, thus freeing the IErrorInfo object.
I would imagine that _com_raise_error will call SetErrorInfo, passing it your IErrorInfo object. The contract for that is that the reference to the info is stored in a thread local, so whenever you set a new info, old one is released. Furthermore, whenever someone calls GetErrorInfo afterwards, ownership of info is transferred to that caller. So it's caller's obligation to call GetErrorInfo after every failed call that may set it, and release the object accordingly.
Thus, SetErrorInfo (as any other conventional COM call) will call AddRef on your object, so you do must not initialize it with a counter of 1.
Adding to the other answers, here are a couple of thoughts:
The general COM rule is that in-parameters do not need to be AddRef:ed at any level, since calls are synchronous and the reference count can't magically change while the method runs.
Every AddRef call represents a new stable reference to the object, that is, after calling AddRef, you can count on the object still being there. That means, if you want to store an interface pointer for later perusal, you should call AddRef. When you no longer care about the object's survival, call Release.
So, since you want to throw an exception object containing an IErrorInfo pointer, that object should AddRef it, since it needs the pointed-to-object to survive. Its destructor would typically Release.
I don't think SetErrorInfo needs to be involved in this -- it's the C alternative to throwing an exception.