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
Related
I thought that this would be a simple problem but I have had some difficulty finding an answer.
I have a struct defined in C++, let's say:
struct MyStruct
{
int a;
int b;
};
This gets wrapped into Java proxy class MyStruct by SWIG. I have a function in C++ which takes an array of struct MyStructs:
void myFunction(struct MyStruct arg[], int amount);
SWIG sees a pointer parameter and therefore generates the Java wrapper of the function to use a single MyStruct object as its parameter:
void myFunction(MyStruct arg, int amount) { /**/ }
How do I get SWIG to generate the Java function to take an array of MyStruct Java objects? I have been able to figure it out for arrays of primitive types but have not found a way to get it working for custom wrapped types.
So my desired Java function signature would be this:
void myFunction(MyStruct[] arg, int amount);
Edit: Updated wording to use proper SWIG nomenclature of proxy classes.
I was able to create a working solution using an intermediary array class generated using %array_class from carrays.i along with in and javain typemaps. A complete working example with the solution can be found in my gist.
If anyone can come up with a better solution or improvements then I would be much appreciated. A drawback of my solution is that you would need to create an additional Java array proxy class for each different proxy class that you wanted to use in this way, which could clutter up the Java API. This could be improved slightly by making the array proxy classes package-private using the javaclassmodifiers typemap.
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'm learning Scala at the moment and I came across this statement in Odersky's Programming Scala 2nd edition:
one way in which Scala is more object-orientated than Java is that classes in Scala cannot have static members.
I'm not sufficiently experienced in either Java or Scala to understand that comparison. Why does having static members make a language less OO?
Odersky's statement is valid and significant, but some people don't understand what he meant.
Let's say that in Java you have a class Foo with method f:
class Foo {
int f() { /* does something great */ }
}
You can write a method that takes a Foo and invokes f on it:
void g(Foo foo) { foo.f(); }
Perhaps there is a class SubFoo that extends Foo; g works on that too. There can be a whole set of classes, related by inheritance or by an interface, which share the fact that they can be used with g.
Now let's make that f method static:
class Foo {
static int f() { /* does something great */ }
}
Can we use this new Foo with g, perhaps like so?
g(Foo); // No, this is nonsense.
Darn. OK, let's change the signature of g so that we can pass Foo to it and have it invoke f.
Ooops -- we can't. We can't pass around a reference to Foo because Foo is not an instance of some class. Some people commenting here are confused by the fact that there is a Class object corresponding to Foo, but as Sotirios tried to explain, that Class object does not have an f method and Foo is not an instance of that class. Foo is not an instance of anything; it is not an object at all. The Class object for Foo is an instance of class Class that has information about Foo (think of it as Foo's internal Wikipedia page), and is completely irrelevant to the discussion. The Wikipedia page for "tiger" is not a tiger.
In Java, "primitives" like 3 and 'x' are not objects. They are objects in Scala. For performance your program will use JVM primitives for 3 and 'x' wherever possible during execution, but at the level you code in they really are objects. The fact that they are not objects in Java has rather unfortunate consequences for anyone trying to write code that handles all data types -- you have to have special logic and additional methods to cover primitives. If you've ever seen or written that kind of code, you know that it's awful. Odersky's statement is not "purism"; far from it.
In Scala there is no piece of runtime data that is not an object, and there is no thing you can invoke methods on that is not an object. In Java neither of these statements in true; Java is a partially object-oriented language. In Java there are things which are not objects and there are methods which aren't on objects.
Newcomers to Scala often think of object Foo as some weird replacement for Java statics, but that's something you need to get past quickly. Instead think of Java's static methods as a non-OO wart and Scala's object Foo { ... } as something along these lines:
class SomeHiddenClass { ... }
val Foo = new SomeHiddenClass // the only instance of it
Here Foo is a value, not a type, and it really is an object. It can be passed to a method. It can extend some other class. For example:
abstract class AbFoo { def f:Int }
object Foo extends AbFoo { def f = 2 }
Now, finally, you can say
g(Foo)
It is true that a "companion object" for a class is a good place to put non-instance methods and data for the class. But that companion object is an object, so the usual rules and capabilities apply.
The fact that in Java you put such methods on non-objects -- limiting how they can be used -- is a liability, not a feature. It is certainly not OO.
I am not sure I completely buy that argument, but here is one possible reasoning.
To an object-oriented purist, everything should be an object, and all state should be encapsulated by objects. Any static member of a class is by definition state which exists outside of an object, because you can use it and manipulate it without instantiating an object. Thus, the lack of static class members makes for a more pure object-oriented language.
Well, with static members like methods you don't have any objects to create and nevertheless you can call such static methods. You only need the static classname in order to set the namespace for these methods, for example:
long timeNow = System.currentTimeMillis(); // no object creation
This rather gives a feeling like in procedural languages.
static members belongs to the Class not to the object while the main concept of oop lies among the relation between the individual objects of dirrefer Class.
A static method in Java is one that operates on the class itself, and doesn't need an Object to be created first. For example, this line:
int c = Integer.parseInt("5");
Integer.parseInt() is static because I didn't have to go Integer i = new Integer(); before using it; this isn't operating on any particular object that I've created, since it's always going to be the same, and is more like a typical procedural function call instead of an object-oriented method. It's more object-oriented if I have to create an object for every call and we encapsulate everything that way instead of allowing static to use methods as faux-procedural-functions.
There are several competing definitions of what exactly object-orientation means. However, there is one thing they all can agree on: dynamic dispatch is a fundamental part of the definition of OO.
Static methods are static (duh), not dynamic, ergo they are by definition not object-oriented.
And logically, a language that has a feature which isn't object-oriented is in some sense "less OO" than a language which doesn't have said feature.
I want to write a Java2Go generator, but I find it hard to express polymorphism (e.g.: formal arg is Base class, but real arg is Sub class), how do I express blow code in Go?
class Base{
public int i;
}
class Sub extends Base{
}
class Test{
public static int test(Base base){
base.i = 99;
return base.i;
}
public static void main(String [] args){
Sub sub = new Sub();
System.out.println(test(sub));
}
}
You'll need to duplicate your code or make wrappers that calls a common utility function that it'll basically be madness.
There's no elegant way to do a "function by function translation". The elegant way to do it is to write your program in a different way.
A Go program will fundamentally have to be structured differently. From years of writing object oriented code it's a hard habit to shake, but when I figure out the "Go-like" way to solve the problems it usually works out to be simpler over time.
Having proper inheritance and all that appears to save code and keep things neat and tidy, but - at least in my experience - over years of development it easily ends up like a tangled mess, or at least hard to dig into if you haven't worked with the code for a while.
Go's interfaces are much more limited, but it'll force you to keep things simpler and more "obvious". The separation between the different classes is explicit.
There are also some advantages; it's much easier to "mix" types than with inheritance after you get some experience how to do it. Another "trick" is that a type can satisfy more than one interface for example.
If you've been writing object oriented code forever then it'll take some practice getting used to the new tools. I'd suggest instead of writing a translator, just try to write some Go based tools. It'll be fun. :-)
Here's what I came up with.
When extending a class, add the parent class as a embedded struct and attach a hidden method to the child class/struct to convert back to the parent class/struct.
For functions that accept Objects, have them accept pointers to structs.
Run from start.go
File: Test.go
package Test
import (
"fmt"
)
type Base struct{
I int
}
type Sub struct {
Base
}
func (s *Sub) _toBase() *Base{
return &s.Base
}
func Test( base *Base) int{
base.I = 99;
return base.I;
}
func Main( args []string) error{
sub := Sub{}
fmt.Println(Test(sub._toBase()));
return nil
}
File: start.go
package main
import (
"so-java2go/javaStructs/Test"
"os"
)
func main(){
Test.Main(os.Args)
}
File: Test.java
class Base{
public int i;
}
class Sub extends Base{
}
class Test{
public static int test(Base base){
base.i = 99;
return base.i;
}
public static void main(String [] args){
Sub sub = new Sub();
System.out.println(test(sub));
}
}
If you just have member variables in your classes, then you can use embedding. However, this solution isn't going to extend to the case where you also want methods on your classes, which can be overridden in subclasses, because the name-collisions will prevent your Go code from compiling.
You could compile classes to a raw-memory struct with a vtable (as if you were compiling to assembler or C), but then you'd have to implement your own garbage collector. Assuming that's not what you want, you can extend the vtable idea to include methods to return the address of member variables, which will allow you to use Go interfaces as a cheap way of implementing the vtable. Here's some code, slightly compressed to reduce the appearance of the boilerplate.
package main
import "fmt"
type Base struct {
i int
}
func (b *Base) get_i() *int { return &b.i }
func NewBase() *Base { return &Base{} }
type Sub struct {
parent Base
}
func NewSub() *Sub { return &Sub{*NewBase()} }
func (s *Sub) get_i() *int { return s.parent.get_i() }
type BaseI interface {
get_i() *int
}
func test(b BaseI) int {
*b.get_i() = 99
return *b.get_i()
}
func main() {
s := NewSub()
fmt.Println(test(s))
}
Methods will need to be name-mangled, since Java allows overloading. You'll find it fun to figure out exactly which method needs to be called at a given call site, depending on the type of the object and the types of all the method arguments :)
In fact, lots of things will end up needing to be name-mangled. For example, the above code translates the class names 'Base' and 'Sub' directly, but what if I'd called one of the classes 'main', or I'd called 'Sub', 'NewBase' (which didn't appear in the original Java source, but appeared during the translation process)? Typically, translated code would look more like this to avoid these sorts of problems:
type Java_class_Base struct {
Java_member_i Java_basetype_int
}
There's plenty of other hurdles. For example, the code above translates Java int to Go int, but the two are not the same. Go's int32 is closer, but still behaves differently (for example, Java specifies what happens on overflow, but Go doesn't). This means that even a simple expression like x = x + 1 is hard to translate, since you're going to have to write your own add function to make sure the translated code behaves identically to the Java code. Another example is that every object can potentially act as a thread-reentrant lock (since it can be synchronised on). That means that you're going to have to decide how to translate that, which is going to involve having a notion of Java thread, and being able to figure out which Java thread your translated call is executing on.
Good luck! There's a lot of difficulties ahead, but it's a fun challenge to make a compiler.
I know well, what is a class literal in java, I just wonder, what is the reason for the .class in the syntax. Is there any ambiguity removed by this? I mean, wouldn't an alternative Java syntax using
Class<String> c = String;
instead of
Class<String> c = String.class;
work? To me the class keyword looks like a boilerplate.
Sure, you could make that the syntax. But using the .class suffix makes the compiler's job easier; it has to do less work to know that the code is syntactically correct.
Without the suffix, the compiler would have to work harder to understand the difference between this:
String.getName() // a method inherited from java.lang.Class<T>
and this:
String.valueOf(...) // a static method from java.lang.String
If you don't think that the .class suffix is needed, do you also think that the f and L suffices are useless (for float and long literals, respectively)?
It's just not the same thing. String is a class of type string, and String.member is one of its member variables, String.method() would be one of its methods.
String.class is an object of type Class that defines String. It seems a lot more intuitive that you need to specify .class to indicate that you're trying to refer to an object of type Class.
Not to mention that it's easier to parse this kind of construct, and potentially prevents bugs where you're accidentally returning a Class object when you didn't mean to.
This is even more relevant when you're looking at inner classes, like OuterClass.InnerClass.class.
To work with Matt's example: How would you work on the class object without having to create a temporary variable first? Assuming your class Foo has a static method called getClasses, how would you differentiate between Foo.getClasses and Foo.class.getClasses?
String is the String class pseudo-object which provides access to the classes static fields and methods, including class, which refers to the Class instance which describes the String class. So they are distinct, but because Java doesn't have the metaclass arrangement of (say) Smalltalk-80 this isn't very clear.
You could certainly make String and String.class synonymous if you wanted to, but I think there is a valid basis for the distinction.
Let's use integer as an example:
Class<Integer> c = Integer; // your proposal
int i = Integer.MAX_VALUE; // compare with below
int j = c.MAX_VALUE; // hmm, not a big fan, personally
It just doesn't seem to flow, in my opinion. But that's just my opinion :)