I am reading the jdk 19(support the m1 chip when compile) source code, in the refactor source code in reflection.cpp, the function look like this:
oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) {
oop mirror = java_lang_reflect_Method::clazz(method_mirror);
int slot = java_lang_reflect_Method::slot(method_mirror);
bool override = java_lang_reflect_Method::override(method_mirror) != 0;
}
when I tracing this clazz function java_lang_reflect_Method::clazz:
oop java_lang_reflect_Method::clazz(oop reflect) {
return reflect->obj_field(_clazz_offset);
}
the obj_field function get the oop data from heap. This makes me a little confusing, the heap store the all object instance, why the reflection get data from heap? I think it will get the metadata from Method Area because in there store the class metadata, using the metadata, could construct the class info. the obj_field look like this:
inline oop oopDesc::obj_field(int offset) const { return HeapAccess<>::oop_load_at(as_oop(), offset); }
This reads the clazz field of a java.lang.reflect.Method object.
java.lang.reflect.Method is a regular Java class (with some support from native helpers). Why do you expect it not to be stored on the heap?
Note that java.lang.reflect.Method is not the same as a hotspot-internal C++ class Method.
The class Method is an implementation detail of the hotspot JVM engine and instances of this internal C++ class are never stored on the heap.
Related
I'm trying to call from C++ into java. I've understood the cux of this answer but I feel I'm not able to achieve the last mile. What classes and methods do I have to use to call Java from C++?
Also not enough points to post comments on there. I basically get that I create the object from java and pass it along in one of my calls into C++. I then get that I could potentially cache it or immedately call into the callback.
This is how my djinni file looks like
my_client_interface = interface +j {
log_string(str: string): bool;
}
get_my_record = interface +c {
static create(): get_my_record;
method_returning_nothing(value: i32);
add_to_string(value: string);
method_returning_something(key: my_record): my_record;
set_callback(cb: my_client_interface);
}
I have no issue creating and passing along the logger callback from java but what concrete class do I call the logger against.
void GetMyRecordImpl::set_callback(const std::shared_ptr<MyClientInterface> & cb)
{
cb->???????
}
since MyClientInterface is still abstract it errors out obviously with
error: member access into incomplete type 'std::__ndk1::shared_ptr<helloworld::MyClientInterface>::element_type' (aka 'helloworld::MyClientInterface')
But if I implement a concrete class against it obviously it's going to call the concrete classes log method and not the one in java. I do see what I need in
bool NativeMyClientInterface::JavaProxy::log_string(const std::string & c_str) {
auto jniEnv = ::djinni::jniGetThreadEnv();
::djinni::JniLocalScope jscope(jniEnv, 10);
const auto& data = ::djinni::JniClass<::djinni_generated::NativeMyClientInterface>::get();
auto jret = jniEnv->CallBooleanMethod(Handle::get().get(), data.method_logString,
::djinni::get(::djinni::String::fromCpp(jniEnv, c_str)));
::djinni::jniExceptionCheck(jniEnv);
return ::djinni::Bool::toCpp(jniEnv, jret);
}
but how would I create the NativeMyClientInterface object needed from the shared_pointer pointing to my abstract class MyClientInterface ?
I wasn't including #include "my_client_interface.hpp" :| the error makes so much sense now.
If you want to use Java object in your C++ code, you got to implement and instantiate that object in Java. Djinni may be perceived as Java Native Interface (JNI) code generator. What you need is Java application, which parts are implemented in C++.
Each interface declared in Djinni is generated for C++ and Java (or Objective-C), so there must be two classes with implementation. One is generated by Djinni and it is a proxy that allows cross-language communication. The other one must be implemented by a programmer.
Regarding your compilation error, I believe you are missing an include directive in the file where GetMyRecordImpl is defined, something like:
#include "generated/MyClientInterface.hpp"
I want to know what the modern C++11 equivalent of Java's instanceof. I have seen this SO post but it is quite old and was wondering if there's a more modern, better solution in C++11?
I was hoping there's a possibility of using a switch construct without having to resort to a manual enum class.
class A {
};
class B : public A {
}
class C : public A {
}
on_event(A& obj)
{
switch (obj) {
case A:
case B:
case C:
}
}
My base class does not have any virtual methods or functions. I am representing an expression tree for a parser and the base class is just a polymorphic holder - like an ADT in Haskell/OCaml.
The same answer still applies, and has always been like this in C++:
if (C * p = dynamic_cast<C *>(&obj))
{
// The type of obj is or is derived from C
}
else
{
// obj is not a C
}
This construction requires A to be polymorphic, i.e. to have virtual member functions.
Also note that this behaviour is different from comparing typeid(obj) == typeid(C), since the latter tests for exact type identity, whereas the dynamic cast, as well as Java's instanceof, only test for the target type to be a base class of the type of the most-derived object.
In C++ plain old data (POD) has no runtime type information. The classes described all take exactly 1 byte, and have identical runtime representations in any compiler with the empty base class optimization.
As such what you want cannot be done.
Adding a virtual destructor to the base class adds in RTTI, and dynamic_cast support.
Adding an enum or int field to the base that gets initialized differently for each derived class also works.
Yet another option is to create a template function, and store a pointer to it, like so:
using my_type_id=void(*)();
template<class>void get_my_type_id_helper(){};
template<class T> my_type_id get_my_type_id(){return get_my_type_id_helper<T>;}
and then storing a my_type_id in A initialized appropriately. This is reinventing RTTI, and as you want more features you will approach C++ RTTI overhead.
In C++ you only pay for what you ask for: you can ask for classes without RTTI, which you did, and get it.
RTTI is Run Time Type Information. POD is plain old data, a C++03 term. Many classes are not POD: the easy way is to add a virtual destructor. C++11 has more fine grained standard layout and aggregate terms.
Technically RTTI and POD are not opposites of each other: there are classes with no RTTI that are not POD.
Note that MSVC has options to not generate RTTI and its aggressive Comdat folding can break the manual RTTI I did above, in both cases in violation of the standard.
Maybe you are interested in the answer I've posted inside your mentioned old SO post.
https://stackoverflow.com/a/49296405/1266588
The answer presents an implementation of instanceof without the usage of dynamic_cast based on C++11, template metaprogramming and RTTI. A small performance measurement application demonstrates that it is more efficient than dynamic_cast if you use compiler optimization.
Don't do that. In most cases you should review your design when you ask for instanceof or dynamic_cast.
Why? You are most likely violating Liskov's substitiontin principle.
How about this approach:
class A {
public:
virtual void action();
virtual ~A();
};
class B : public A {
public: void action() override;
};
class C : public A {
public: void action() override;
};
void on_event(A& obj)
{
obj.action();
}
Note that as #Yakk pointed out you need at least one virtual method anyway to get dynamic polymorphism. And there is a rule that says: When you have at least one virtual method, always also write a virtual destructor in the base class.
You can do all this with templates and specialization or type tagging but I take from your question -- coming from Java -- you don't want to go there yet. You really like virtual methods, don't you? Sorry, that you have to mark them in C++.
If you're willing to limit yourself to types known at compile-time (rather than working through pointers on instances of classes with vtables) - then C++11 and later does have an instanceof equivalent: It is std::is_base_of.
You might also want to check out std::is_convertible and std::is_same.
I have a C API that I'm trying to use within Clojure, through the JNA API. My issue can best be demonstrated with the following example. Say I have this C code in a library:
typedef struct {
int foo;
int bar;
double baz;
} MyStruct;
MyStruct createStruct() {
MyStruct myStruct;
myStruct.foo = 3;
myStruct.bar = 4;
myStruct.baz = 3.14;
return myStruct;
}
double addStruct(MyStruct myStruct) {
return myStruct.foo + myStruct.bar + myStruct.baz;
}
In this example, I'd like to call createStruct, and then pass that result to addStruct. The important point here is that MyStruct is passed by value as both a return type and an argument. At no point do I need to actually read the values of the fields in MyStruct.
Additionally, in my system, native functions are wrapped like this:
; `quux` is defined in `some-lib` and returns an `int`
(let [fn- (com.sun.jna.Function/getFunction "some-lib" "quux")]
(fn [& args]
(.invoke fn- Integer (to-array args))))
The goal is to get a type to substitute for Integer above that will wrap MyStruct as a value.
The only resource that I've found covering this subject is this article, but it only discusses how to pass structs by reference.
Given that, here are the different approaches I've tried to take to solve this problem:
Create a class that inherits from Structure, which is JNA's built-in mechanism for creating and using structs. Given the information on that page, I tried to create the following class using only Clojure:
class MyStruct extends Structure implements Structure.ByValue {
int foo;
int bar;
double baz;
}
deftype doesn't work for this scenario, since the class needs to inherit from the abstract class Structure, and gen-class doesn't work because the class needs to have the public non-static fields foo, bar and baz.
From what I can tell, none of the standard Clojure Java interop facilities can create the above class.
Create a class that inherits from Structure and override the struct field getter/setter methods. Since gen-class is (I believe) the only Clojure construct that allows for direct inheritance, and it doesn't support multiple public non-static fields, the next alternative is to simply not use fields at all. Looking at the Structure abstract class documentation, it seems like there's a concoction of overrides possible to use 'virtual' struct fields, such that it really gets and sets data from a different source (such as the state field from gen-class). Looking through the documentation, it seems like overriding readField, writeField, and some other methods may have the intended effect, but the I was unclear how to do this from reading the documentation, and I couldn't find any similar examples online.
Use a different storage class. JNA has a myriad of classes for wrapping native types. I'm wondering if, rather than defining and using a Structure class, I could use another generic class that can take an arbitrary number of bits (like how Integer can hold anything that's 4 bits wide, regardless of what type the source 'actually' is). Is it possible to, for example, say that a function returns an array of bytes of length 16 (since sizeof(MyStruct) is 16)? What about wrapping a fixed-size array in a container class that implements NativeMapped? I couldn't find examples of how to do either.
Clojure actually embeds a forked version of ASM, which is used for generating and loading JVM bytecode.
On top of this library, I built small DSL (that's incomplete and probably broken) that allows for creating arbitrary Java classes, with a Java-like syntax. Currently, it's just a GitHub gist, and only supports extending classes, implementing interfaces, adding constructors that call superclass constructors, and fields.
Here's the solution to the above question, using this DSL:
(def-class MyStruct :extends com.sun.jna.Structure
:implements [com.sun.jna.Structure$ByValue]
; Declare all the constructors, which just forward their
; arguments to the constructors of com.sun.jna.Structure
(com.sun.jna.Structure [])
(com.sun.jna.Structure [com.sun.jna.TypeMapper])
(com.sun.jna.Structure [Integer])
(com.sun.jna.Structure [Integer com.sun.jna.TypeMapper])
(com.sun.jna.Structure [com.sun.jna.Pointer])
(com.sun.jna.Structure [com.sun.jna.Pointer Integer])
(com.sun.jna.Structure [com.sun.jna.Pointer Integer com.sun.jna.TypeMapper])
; Declare the fields of the struct
^Integer foo
^Integer bar
^Double baz)
Now, I can do the following:
(defn createStruct [& args]
(let [fn- (com.sun.jna.Function/getFunction "some-lib" "createStruct")]
(.invoke fn- MyStruct (to-array args))))
(defn addStruct [& args]
(let [fn- (com.sun.jna.Function/getFunction "some-lib" "addStruct")]
(.invoke fn- Double (to-array args))))
(addStruct (createStruct))
; => 10.14
How does jvm know what class an object is an instance of at runtime. I know we can use the getClass method to get the class name but how does the getClass method work?
Thx,
Praveen.
The answer? Magic!
No, seriously, it's implementation defined, and an implementation of the JVM need not use a single simple technique, like storing the class as a reference in a field at a constant offset in the instance's data. All it need do is make sure the getClass method observably works as documented. For example, with escape analysis, a JVM may allocate an instance statically on the heap, because it knows the instance doesn't outlive the stack frame. In this case, it may elect to turn a getClass() call into a direct load of the Class instance, rather than a method call at all! Similarly, since getClass() is logically a virtual method (I know it's final but its return value is constant across all instances of a class from any given class loader but different for each distinct class, as if it were a virtual that returned a constant value), it may undergo similar optimizations to inline caching.
I don't know the specifics of the JVM, but in most object oriented language + runtime systems (Delphi, C++, .NET), a hidden field is added to the object instance data which points to the object instance's type information.
You have to be careful of this when mapping an object instance directly onto an external data structure because the hidden type info or virtual method table pointer in the object instance data will throw off alignment with the fields in the external data structure.
You can usually see this artifact by looking at the size of the object instance. Sizeof() or equivalent. An object with no declared fields will still have a memory footprint greater than zero. That's where the type info magic comes from.
http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html
As previous answers suggested, the implementation is not specified.
To get an idea of how an implementation could look, I looked into the runtime part of a recent Hotspot JVM.
In Hotspot every object starts with a mark word (for GC and other uses), and a klass pointer.
If you call the getClass, the native implementation in Object.c will get called:
JNIEXPORT jclass JNICALL
Java_java_lang_Object_getClass(JNIEnv *env, jobject this)
{
if (this == NULL) {
JNU_ThrowNullPointerException(env, NULL);
return 0;
} else {
return (*env)->GetObjectClass(env, this);
}
}
The GetObjectClass is part of the JNI API. (http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html)
The internal implementation of the JNI GetObjectClass really just resolves the object pointer, reads the klass from the class pointer,
and returns the Java representation of that class:
JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
JNIWrapper("GetObjectClass");
HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
Klass* k = JNIHandles::resolve_non_null(obj)->klass();
jclass ret =
(jclass) JNIHandles::make_local(env, k->java_mirror());
HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
return ret;
JNI_END
I'm currently using both C++ and Java in a project and I'd like to be able to send an object which is contained in C++ to my Java interface in order to modify it via a GUI and then send the modification back in C++.
So far I've been returning either nothing, an int or a boolean to Java via the JNI interface. This time I have to send an object through the interface. I have made similar class definition available both in C++ and in Java. I'd like to know how I'd go about creating the object so that I can use it in Java.
In C++ I have:
JNIEXPORT MyObject JNICALL Java_ca_X_Y_Z_C_1getMyObject(JNIEnv* env, jclass, jint number);
This function would get called by Java in order to get the object from the C++ side (the object is contained in a singleton, easily accessible).
On the Java end, I do a simple call to this method,
MyObject anObject = C_getMyObject(3);
which should return me the newly created object.
Java currently returns me a UnsatisfiedLinkError when I do the actual call. What is wrong?
Here's the solution I opted to use:
First, I would create a similar object in Java. Then, from C++ I would instanciate it and pass it all the values.
(C++)
clazz = env->FindClass("java/lang/Integer");
jmethodID method = env->GetMethodID(clazz, "<init>", "(I)V");
return env->NewObject(clazz, method, (jint)anInteger);
But then I realised this wasn't very portable and was a bit too complicated.
Instead, I decided to return a string that Java would parse and use to initialize the object on its side.
(JAVA)
String aString = "valuesoftheobject";
MyObject myObject(aString);
MyObject would have a constructor which takes a string. I believe the solution is simple and effective.
Another tool you should look at is SWIG. SWIG is a great tool for generate wrappers in other languages (such as Java, Python or C#) for existing C/C++ objects. It will generate automatic Java wrappers around C/C++ objects, and do all the heavy JNI lifting for you.
I use it extensively in Xuggler. To see an example, if you download the Xuggler source code there is a C++ object here:
csrc/com/xuggle/xuggler/IStreamCoder.h
I define a SWIG interface file here:
csrc/com/xuggle/xuggler/IStreamCoder.i
And when run through Swig it generates a Java object (which is stored here)
generate/java/com/xuggle/xuggler/IStreamCoder.java
We can then access that object from Java easily (well, I add some ref counting stuff, but that's pretty advanced). Hope that helps.
Art
If your MyObject class is defined in C++, you're not going to be able access its methods in Java. I'd try to define a Java wrapper class around your C object:
Java:
public C_Object() {
handle = createHandle();
}
private native long createHandle(); // or whatever pointer/handle type?
public void doStuff() {
_doStuff(handle);
}
private native void _doStuff(long handle);
If you can extrapolate a C api instead, you might try JNA.
Your UnsatisfiedLinkError may be the extra character in your function name as written above, or perhaps it can't handle the MyObject return value?