With SWIG am able to create simple bindings for my C++ code.
My question here is for multiple inheritance.
Our C++ codebase has a iClass as base class, which acts as interface. Also we have classes that are derived from two classes, one of which is this interface class.
Now my question is can we use SWIG to create bindings for such a codebase, assuming that we can put our class iClass as an Interface in Java.
It is still multiple inheritance but a very specific case of it and is analogous with interface concept of java.
The case with SWIG is that it indeed will only extend the first base class you list (in the code example below that would be I1) and omit the rest. Interestingly, the C++ compiled code WILL include all the base methods, they are just not available to the Java JNI wrapper.
Multiple inheritance is another paradigm than interfacing, making it hard to cast / interpret an Object in Java as belonging to a particular interface.
What you can do though - which does feel a tad fugly - is to add a compiler directive to the header file of the class which is inheriting from multiple classes. Like so:
class Foo : public I1, I2
{
public:
Foo();
~Foo();
#ifdef SWIG
void aI2Method();
double aI2Property;
#endif
protected:
void bar();
}
When compiling with SWIG, property SWIG is defined. As such the method "aI2Method" and public property "aI2Property" (which for the sake of argument, we assume are defined in base class I2) are used by SWIG and defined in the JNI wrapper for this class "Foo". Just add the public methods / properties in between the conditional directive.
In Java you can then invoke "aI2Method" on Foo or get/set the public "aI2Property"-property, and the native compiled code will invoke these on the I2 base class. Note that this means you don't need to add the same directive including the definitions or function bodies of these methods in the .cpp file of "Foo", as placing it in the header file will suffice. This way, at least the .cpp files remain clean.
Related
I am looking for a java equivalent to the C# extension methods feature. Now I have been reading about Java 8's default methods, but as far as I can see, I can only add these to interfaces...
...is there any language feature that will allow me to write an extension method for a final class that doesn't implement an interface? (I'd rather not have to wrap it...)
Java doesn't have extension methods. Default methods are not extension methods. Let's look at each feature.
Default methods
Both Java and C# support this feature
Problems solved:
Many objects may implement the same interface and all of them may use the same implementation for a method. A base class could solve this issue but only if the interface implementors don't already have a base class as neither java nor C# support multiple inheritance.
An API would like to add a method to an interface without breaking the API consumers. Adding a method with a default implementation solves this.
Java's or C#'s default methods are a feature to add a default implementation to an interface. So objects that extend an interface don't have to implement the method, they could just use the default method.
interface IA { default public int AddOne(int i) { return i + 1; } }
Any object that implements IA doesn't have to implement AddOne because there is a default method that would be used.
public class MyClass implements IA { /* No AddOne implementation needed */ }
C# now has this feature in C# 8 (or .Net 5)
C#'s Extension Method
Problems solved:
Ability to add methods to sealed classes.
Ability to add methods to classes from third-party libraries without forcing inheritance.
Ability to add methods to model classes in environments where methods in model classes are not allowed for convention reasons.
The ability for IntelliSense to present these methods to you.
Example: The type string is a sealed class in C#. You cannot inherit from string as it is sealed. But you can add methods you can call from a string.
var a = "mystring";
a.MyExtensionMethed()
Java lacks this feature and would be greatly improved by adding this feature.
Conclusion
There is nothing even similar about Java's default methods and C#'s extension method features. They are completely different and solve completely different problems.
C# extension methods are static and use-site, whereas Java's default methods are virtual and declaration-site.
What I believe you are hoping for is the ability to "monkey-patch" a method into a class you do not control, but Java does not give you that (by design; it was considered and rejected.)
Another benefit of default methods over the C# approach is that they are reflectively discoverable, and in fact from the outside, don't look any different from "regular" interface methods.
One advantage of C#'s extension methods over Java's default methods is that with C#'s reified generics, extension methods are injected into types, not classes, so you can inject a sum() method into List<int>.
Above all, the main philosophical difference between Java's default methods and C#'s extension methods is that C# lets you inject methods into types you do not control (which is surely convenient for developers), whereas Java's extension methods are a first-class part of the API in which they appear (they are declared in the interface, they are reflectively discoverable, etc.) This reflects several design principles; library developers should be able to maintain control of their APIs, and library use should be transparent -- calling method x() on type Y should mean the same thing everywhere.
C# extension methods are just syntactic sugar for static methods that take the extended type as first argument. Java default methods are something completely different. To mimic C# extension methods, just write usual static methods. You will not have the syntatic sugar, however; Java does not have this feature.
Java default methods are real virtual methods. For example, they can be overridden. Consider a class X inheriting from an interface I that declares a default foo() method. If X or any of its super classes declares no own foo() method, then X will get the foo() implementation of I. Now, a subclass Y of X can override X.foo() like a usual method. Thus, default methods are not only syntactic sugar. They are real extensions of the method overriding and inheritance mechanism that cannot be mimicked by other language features.
Default methods even require special VM support, so they are not even a compiler only feature: During class loading, the hierarchy of a class has to be checked to determine which default methods it will inherit. Thus, this decision is made at runtime, not at compile time. The cool thing about it is that you do not have to recompile a class when an interface it inherits gets a new default method: The VM will, at class load time, assign that new method to it.
It is possible to have extension methods with some tricks.
You may give a try to Lombok or XTend. Although extension methods don't come with the out of the box Java implementation, both Lombok and XTend offers a fully working solution.
Lombok is a simple standalone code processing framework, which makes most of the criticized Java specific hassle less painful, including extension methods:
https://projectlombok.org/features/experimental/ExtensionMethod.html
Xtend http://www.eclipse.org/xtend/ goes a few lightyears forward, and implements a language which is a combination of the best parts of modern languages such as Scala on top of Java and Java type system. This allows implementing some classes in Xtend and others in Java within the same project. The Xtend code complies to valid Java code, so no JVM magic happens under the hood. On the other hand, it is a little too much if you have only extension methods missing.
JPropel https://github.com/nicholas22/jpropel-light implements LINQ style extension methods in Java using Lombok. It may worth of a peek :)
I come from a C++ background and am trying to learn Java now . For C++ classes , we often split the interface and implementation files into foo.h and foo.cpp respectively. After which we would link the files using the #include statement
For Java , how do i split the interface and implemenation into two separate files similar to what I have done in C++ , what are the steps to be taken ??
In Java there's no such distinction.
The closest thing you can do is to have a strict separation of interfaces and implementation of interfaces (something usually recommended).
so for example you can have a
IMyInterface.java
public interface IMyInterface {
}
and a MyImplementation.java
public class MyImplementation implements IMyInterface {
}
However... this is not the same.... it is more like C++ abstract classes and C++ implementation classes.
There's the interface keyword which allows you to declare the public API, which the implementing class can use implements to leverage. This is as close as you can get to your desired separation. Java is simply designed differently, there is no such thing as header files. Header files do not serve as interfaces in c++ anyways, they're just the compiler-required units so the compiler knows where to find method signatures.. The more correct equivalent in C++ for the concept of an interface is the abstract base class.
For the answer to why... well, I'll just direct you to this already-answered question here
... we often split the interface and implementation files into foo.h and foo.cpp ...
That's not true, you are confusing the terms class declaration and (abstract) interface.
Java has no concept of header files, nor does it distinguish class declaration from class definition.
I wrote a set of C++ classes and created a DLL that exports one of these C++ classes. I need to instantiate the exported C++ class in a Java class. Is that possible?
I searched the web for a possible solution, but all I have found where solutions using JNA or JNI that import C++ functions only.
Yes, you can instantiate a C++ class from Java.
One way is with SWIG, which can generate Java wrappers for C++ classes.
For example, given a C++ class like this:
class MyClass {
public:
MyClass();
int myMethod( int arg );
}
SWIG allows you to write Java code like this:
MyClass myclass = new MyClass();
int val = myClass.myMethod( 42 );
If you want to instantiate a C++ class from Java, you'll have to write a little glue code (in C++) that instantiates the desired object. Further, you'll need a Java class that corresponds to the C++ class, and you need to have the glue code convert the C++ object into an object of the Java class aforementioned, and keeps them together (i.e., changes to the C++ object should reflect to the Java object, and the other way around).
This tutorial seems to have some pointers how you could do that. Specifically, it tells you how to instantiate a Java object, which is what you will need for the above approach.
I'm using SWIG to generated Java classes and I have 3 different classes that one dependant on the others.
SWIG makes pointers to this classes because it didn't know about it, I need that SWIG uses the Java classes that created and not the pointers that SWIG creates.
How can I do this?
I have c++ function like this:
bool foo(class1& parm);
Now I use SWIG to create class1 in Java and I want to make SWIG to wrap foo in Java with the parameter class1 that it created and not SWIG_P_class1. I don't have any way to do this.
Swig hides away details like the actual classes or objects used. If you want to access the real Java objects and class I suggest you use JNI (which gives you access to everything and is likely to be faster)
For types that SWIG knows nothing about (i.e. hasn't seen anything more than a forward declaration) the best wrapper it can generate roughly mirrors what you can do with a forward declared class in C++ - it gets wrapped as something that behaves like an opaque pointer. This is the SWIG_P_class1 you're seeing. You can do sensible things with this, e.g. if you have a method that returns references or pointers to instances you could call that to get an object to pass to foo.
However you probably don't want to use that much in real interfaces, so given a header file we want to wrap that looks like:
class class1;
bool foo(class1& parm);
You can wrap it sensibly by giving SWIG a partial (or complete if you prefer) definition of the class1, e.g.:
%module test
class class1 {
};
%include "test.hh"
will cause a sensible class1 and foo to be exposed on the Java side, so you could use them in Java as in:
test.foo(new class1());
exactly as you'd hope.
You will of course need to provide the generated C++ sufficient knowledge of the class1 class, exactly as you would with any other C++ code. The easiest way to do that is to make your SWIG interface look something like:
%module test
%{
#include "class1_defined_here.hh"
%}
class class1 {
};
%include "test.hh"
Is there something like Java's annotations in C++ ?
For example, the #Override annotation marks a function that it overrides another function, and if it wouldn't, it would give an error at compile time.
I am looking for something like this in C++.
C++11 provides support for generalized attributes, which can be seen as superset of Java annotations, as they can be applied not just to variables/functions, but also to statements, for example. But C++11 defines only syntax for generalized attributes, not means for user to define them.
This article gives good overview of generalized attributes: http://www.codesynthesis.com/~boris/blog/2012/04/18/cxx11-generalized-attributes/
GCC supports this feature from version 4.8, according to: http://gcc.gnu.org/projects/cxx0x.html
To implement support for user-defined attributes, compiler plugins are promising, especially based on high-level language integration, like https://fedorahosted.org/gcc-python-plugin/
C++0x will have this feature, where you can explicitly specify whether a member function is meant to override a base class' function, use a default implementation generated by the compiler and much more.
There is C++0x, which has the override 'annotation'. Or, if you wanted to achieve more of the Java "interface" like-code that errors if you don't implement methods, you could use an abstract class:
class Base {
public:
virtual void foo() = 0;
};
class Extended : public Base {
public:
void foo2() {
cout << "hi" << endl;
};
int main() {
Extended e;
e.foo();
}
This will result in a compiler error if you don't override foo in the base class. The issue, however, is that the base class can't have it's own implementation.
There's nothing in the language for this. The best you could hope for is a compiler-specific option. I'd start by checking the documentation for "pragma" for your compiler.
I'm not sure what JAVA provides in general, but for the specific functionality you mentioned, C++ has the override keyword:
class Derived : public Base {
void foo() override { ... }
};
You'll get a helpful compiler error message if Base doesn't have a corresponding virtual void foo().
Another functionally-similar keyword is final, which can be used to say that the function is an override that can't be further overridden in further-derived classes. (The same keyword can be used to say a class can't be derived from).