JNI local references to classes - java-native-interface

When working with object references in JNI, I can use NewLocalRef to (as the name implies) get a new local reference to the same object.
This is useful when implementing a wrapper in C++. The copy-constructor can invoke NewLocalRef and both instances of the class' destructors can simply use DeleteLocalRef on their own local reference.
I'm also wrapping Java classes using a similar pattern, but calling NewLocalRef with a jclass seems to result in extremely strange (possibly undefined) behaviour.
Is there a way of achieving this using JNI built in functionality, or do I need to write my own reference counter?

Related

C++ conventions regarding passing objects (pointer vs reference)

I'd like to work out conventions on passing parameters to functions/methods. I know it's a common issue and it has been answered many times, but I searched a lot and found nothing that fully satisfies me.
Passing by value is obvious and I won't mention this. What I came up with is:
Passing by non-const reference means, that object is MODIFIED
Passing by const reference means, that object is USED
Passing by pointer means, that a reference to object is going to be STORED. Whether ownership is passed or not will depend on the context.
It seems to be consistent, but when I want to pick heap-allocated object and pass it to 2. case parameter, it'd look like this:
void use(const Object &object) { ... }
//...
Object *obj = getOrCreateObject();
use(*obj);
or
Object &obj = *getOrCreateObject();
use(obj);
Both look weird to me. What would you advise?
PS I know that one should avoid raw pointers and use smart instead (easier memory managment and expressiveness in ownership) and it can be the next step in refactoring the project I work on.
You can use these conventions if you like. But keep in mind that you cannot assume conventions when dealing with code written by other people. You also cannot assume that people reading your code are aware of your conventions. You should document an interface with comments when it might be ambiguous.
Passing by pointer means, that object is going to be STORED. Who's its owner will depend on the context.
I can think of only one context where the ownership of a pointer argument should transfer to the callee: Constructor of a smart pointer.
Besides possible intention of storing, a pointer argument can alternatively have the same meaning as a reference argument, with the addition that the argument is optional. You typically cannot represent an optional argument with a reference since they cannot be null - although with custom types you could use a reference to a sentinel value.
Both look weird to me. What would you advise?
Neither look weird to me, so my advise is to get accustomed.
The main problem with your conventions is that you make no allowance for the possibility of interfacing to code (e.g. written by someone else) that doesn't follow your conventions.
Generally speaking, I use a different set of conventions, and rarely find a need to work around them. (The main exception will be if there is a need to use a pointer to a pointer, but I rarely need to do that directly).
Passing by non-const reference is appropriate if ANY of the following MAY be true;
The object may be changed;
The object may be passed to another function by a non-const reference [relevant when using third party code by developers who choose to omit the const - which is actually something a lot of beginners or lazy developers do];
The object may be passed to another function by a non-const pointer [relevant when using third party code be developers who choose to omit the const, or when using legacy APIs];
Non-const member functions of the object are called (regardless of whether they change the object or not) [also often a consideration when using third-party code by developers who prefer to avoid using const].
Conversely, const references may be passed if ALL of the following are true;
No non-mutable members of the object are changed;
The object is only passed to other functions by const reference, by const pointer, or by value;
Only const member functions of the object are called (even if those members are able to change mutable members.
I'll pass by value instead of by const reference in cases where the function would copy the object anyway. (e.g. I won't pass by const reference, and then construct a copy of the passed object within the function).
Passing non-const pointers is relevant if it is appropriate to pass a non-const reference but there is also a possibility of passing no object (e.g. a nullptr).
Passing const pointers is relevant if it is appropriate to pass a const reference but there is also a possibility of passing no object (e.g. a nullptr).
I would not change the convention for either of the following
Storing a reference or pointer to the object within the function for later use - it is possible to convert a pointer to a reference or vice versa. And either one can be stored (a pointer can be assigned, a reference can be used to construct an object);
Distinguishing between dynamically allocated and other objects - since I mostly either avoid using dynamic memory allocation at all (e.g. use standard containers, and pass them around by reference or simply pass iterators from them around) or - if I must use a new expression directly - store the pointer in another object that becomes responsible for deallocation (e.g. a std::smart_pointer) and then pass the containing object around.
In my opionion, they are the same. In the first part of your post, you are talking about the signature, but your example is about function call.

Why are function objects better than function pointers?

from Wikipedia - Function object
A typical use of a function object is in writing callback functions. A callback in procedural languages, such as C, may be performed by using function pointers.[2] However it can be difficult or awkward to pass a state into or out of the callback function. This restriction also inhibits more dynamic behavior of the function. A function object solves those problems since the function is really a façade for a full object, carrying its own state.
Why do function pointers make it difficult to pass a state into or out of the callback function and dynamic behavior of the function?
if function do not use function pointer how programs can called function
As far as function pointers in C go, you need to pass the state as an extra parameter. That's in opposition to languages like python, javascript or C++ that have closures. And that means storage duration needs to be considered for that extra structure.
C programmers do make use of function pointers. And you can't write very generic code without using function pointers. We just apply discipline and pass the captured state in a structure, as a function parameter.

Passing COM objects as references within module

Is there any reason or convention for not passing COM objects as references to internal functions?
I know that references cannot be used in COM API since that would break binary compatibility. But what about within a module?
It's perfectly OK to pass COM objects by reference to non-COM functions. Even though a reference is just an alias to an object they are typically implemented as pointers under the hood.
The question is fishy, the distinction between objects and interfaces is important in COM. Client code that uses a COM server only ever works with interface pointers. CoCreateInstance() creates an object on the server and returns an interface pointer to one of the interfaces implemented by the coclass. Like IUnknown*. At no point are you ever handling an object. Boilerplate is to leave interface pointers as just pointers and passing them by reference isn't very useful. You could wrap them in a smart pointer class so the Release() call is automatic. Passing that smart pointer object by reference is fine, it doesn't have anything to do with COM.
It could be different in a COM server. You typically implement an object there with a C++ class that implements the COM interfaces. If code in that server needs a reference to that object then it makes sense to just pass a reference to the C++ object. That's just standard usage of references in C++ and doesn't have anything to do with COM.

Boost.Python: Getting a python weak reference to a wrapped C++ object

I've wrapped a C++ class using Boost.Python. These Objects have strong references (boost::shared_ptr) on the C++-side, and there may be intermittent strong references in Python as well. So far, everything works well. However, if I create a python weak reference from one of the strong references, this weak reference is deleted as soon as the last python strong reference disappears. I'd like the weak reference to stay alive until the last strong reference on the C++ side disappears as well. Is it possible to achieve that?
Phrased another way: Is there a way to find out from python if a particular C++ object (wrapped by Boost.Python) still exists?
How are you holding a "C++ strong reference" to the wrapped class ?
I'm quite rusty on boost python, but I believe it's the boost::shared_ptr's deleter presence which ensures lifetime management.
If that isn't the problem, you probably need to hold the instance in C++ in a boost::python::object.

Difference between std::shared_ptr<Type> and Type^

I don't really understand the difference between a shared_ptr and the new handle notation (^) in C++/CX. From what I've read they seem to do the same thing regarding reference counting and memory management. What am I missing?
std::shared_ptr<Type>
//vs
Type^
Solely considering lifetime management, these are the same: a shared_ptr<T> holds a strong (owning) reference to a T object; a T^ does the same. make_shared<T> is roughly equivalent to ref new T in C++/CX.
If everywhere you see a T^ you think shared_ptr<T> or ComPtr<T> or CComPtr<T>, then that's okay--the lifetime management is roughly the same.
How lifetime management works under the hood is different, though: every T type for which T^ is well-formed is a Windows Runtime reference type that implements the IUnknown interface, so the T object is internally reference counted(*). shared_ptr<T> supports arbitrary types and uses external reference counting (i.e., it allocates its own reference counting mechanism to control the lifetime of the object).
For weak references, shared_ptr<T> has weak_ptr<T>, and T^ has WeakReference. WeakReference is not strongly-typed, but you can easily write a strongly-typed reference wrapper around it. Otherwise, weak references work as you would expect them to. Support for weak references is optional: not all reference types support weak references, but most do.
(*) There is one exception: Platform::String^, which is not a Windows Runtime reference type, but is handled specially for a variety of reasons. You can think of it as being the same as any other T^ with respect to lifetime management, though.
So, why do Windows Runtime types wear hats in C++/CX? Why isn't a library solution like shared_ptr<T> or ComPtr<T> used?
It's because you never really have a pointer (or a hat) to a concrete runtime type: you can only interact with an object via a pointer to one of the interfaces that its type implements. Windows Runtime also does not support interface or class inheritance: every interface must derive directly from IInspectable, and class inheritance is emulated through the use of COM aggregation.
In short, there's no library solution that would result in natural looking C++ code with static type safety. Function calls, derived-to-base conversions, and interface conversions usually require a call to QueryInterface to get the right interface pointer.
You can do this with a library solution (see, for example, the WRL library, or pretty much any COM code), but you can't support C++ language features like implicit conversions or dynamic_cast. Without the hats, you're stuck dealing solely with interface pointers and having to call QueryInterface yourself.
(If you're interested in the rationale behind why the C++/CX language extension were developed and how the C++/CLI syntax ended up being selected for reuse, I'd recommend Jim Springfield's post on this blog from last year, "Inside the C++/CX Design". Also of note is episode 3 of GoingNative, in which Marian Luparu discusses C++/CX.)
As far as I can tell, the latter lacks support for weak references and custom deallocation functions.
Note that the former, being more general, accepts any type (in principle), and for safety and cleanliness calls for the use of the helper function make_shared. The latter is supported at a language level. That means code like this is safe in C++/CX:
some_function(ref new foo(), ref new bar());
While in C++, you need to do this:
// bad: if foo is allocated but bar's allocation throws, you leak!
some_function(new foo(), new bar());
// good: both never make it anywhere but into a shared_ptr, no leaks
some_function(make_shared<foo>(), make_shared<bar>());
Other than that, sure, they implement the same concept. If you're in C++/CX land, use the latter syntax for simplicity and uniformity; if you're trying to stick to standard C++, or are wrapping an existing resource management scheme into a reference-counted scheme, then you'll want the former.