Does C++ support anonymous implementation of interface like Java?
Something similar like in following code:
Runnable myRunnable =
new Runnable(){
public void run(){
System.out.println("Runnable running");
}
}
You can get pretty close by creating an instance of an anonymous class that inherits from your defined interface.
Example:
#include <iostream>
struct Runnable {
virtual ~Runnable() = default;
virtual void operator()() = 0;
};
int main() {
struct : Runnable { // anonymous implementation of interface
void operator()() override {
std::cout << "Run Forrest\n";
}
} myRunnable;
myRunnable(); // prints Run Forrest
}
Here's a contrived example, putting base class pointers to instances of different anonymous implementations of Runnable in a std::vector<std::unique_ptr<Runnable>>. As you can see here, making the implementations anonymous serves little purpose. The anonymous type is simply std::remove_reference_t<decltype(*instance)>.
#include <iostream>
#include <memory>
#include <type_traits>
#include <vector>
// Runnable is defined as in the example above
int main() {
// a collection of Runnables:
std::vector<std::unique_ptr<Runnable>> runners;
{ // create a pointer to an instance of one anonymous impl.
struct : Runnable {
void operator()() override {
std::cout << "Foo\n";
}
} *instance = new std::remove_reference_t<decltype(*instance)>;
runners.emplace_back(instance); // save for later
}
{ // create a pointer to an instance of another anonymous impl.
struct : Runnable {
void operator()() override {
std::cout << "Bar\n";
}
} *instance = new std::remove_reference_t<decltype(*instance)>;
runners.emplace_back(instance); // save for later
}
// loop through all `Runnable`s and ... run them:
for(auto& runner : runners) (*runner)(); // prints "Foo\nBar\n"
}
Does c++ support anonymous implementation of interface like java?
No, it does not. You must explicitly define an implementation class to inherit from the interface and override its virtual methods, eg:
class MyRunnableImpl : public Runnable {
public:
void run() override {
std::cout << "Runnable running";
}
};
Runnable *myRunnable = new MyRunnableImpl;
...
delete myRunnable;
No. C++ does not have this feature. C++ has different solutions for the problems that Java solves with such on-the-fly implementations of interfaces. Though, having accepted that, maybe we can still learn something by considering how it could be emulated in C++
#include <iostream>
#include <type_traits>
struct Runnable {
virtual void run() = 0;
virtual ~Runnable() = default;
};
template <typename F>
auto make_runnable(F f){
struct Runnable_Impl : Runnable {
F f;
Runnable_Impl(F f) : f(f) {}
void run() override {
f();
}
};
return Runnable_Impl{f};
}
void foo(Runnable& r){ r.run(); }
int main(){
auto runnable = make_runnable( [](){ std::cout << "hello world\n";});
runnable.run();
foo(runnable);
auto runn2 = make_runnable( [](){ std::cout << "hello world\n";});
std::cout << std::is_same_v<decltype(runnable),decltype(runn2)>;
}
Output:
hello world
hello world
0
Inside make_runnable the type has a name, but because each lambda expression is of different type, a call to make_runnable with a different lambda will yield a different type as you can see by comparing the types of the returned objects (is_same yields false). It could be anonymous, but as the caller doesn't get to see the name, that doesn't matter that much.
I haven't seen this or similar in the wild, though thats not a big surprise because C++ relies much less on interfaces and inheritance than Java.
Related
I have the Java code below:
public class JavaToC {
protected void hereIsYourCallback(long l, double d, boolean b, Object obj) {
// this should be implemented by subclasses
}
public void start() {
try {
while(true) {
Thread.sleep(5000);
hereIsYourCallback(3L, Math.PI, true, "Hello from Java!");
}
} catch(InterruptedException e) {
// NOOP
} catch(Exception e) {
e.printStackTrace();
}
}
}
Is it possible to write a C++ code that would somehow trap every JVM call to hereIsYourCallback? Note that this callback would have to come from an embedded JVM instantiated through JNI_CreateJavaVM.
if you're still looking for a solution: you need to use the RegisterNatives() function in jni.h. With that, you can register functions present on the host (c/c++) environment to native methods on the embedded jvm.
see this question for more informations, but the gist is, supposing a class with a native void printingFromC() method:
create your function like this:
JNIEXPORT void JNICALL printingFromC (JNIEnv* env, jobject thisObject) {
printf("Hello there!");
}
describe your native methods like this (the first string is the method name in java, doesn't need to match the C/C++ function name:
static JNINativeMethod methods[] = {
{"printingFromC", "()V", (void*) &printingFromC },
};
Then after loading the class, before calling any native methods, register them:
myCls = (jclass) (*env)->FindClass(env, "my/path/MyClass");
(*env)->RegisterNatives(env, myCls, methods, sizeof(methods)/sizeof(methods[0]));
I hope this helps.
I have a C++ library that I have to use in an existing Android implementation. I'm using Android NDK and using the C++ classes via JNI.
However, I am not able to find how to subclass a C++ abstract class in Java using JNI.
Problems I face:
My aim is to provide Java implementation for the virtual methods in C++ by subclassing the abstract C++ class.
I have loaded the native library and I'm trying to declare the native methods.
The C++ methods have keyword 'virtual'. When I declare the native functions in Java after loading the C++ library, 'virtual' is not recognized. What is wrong here?
Any help is appreciated. I'm a newbie to JNI. Thanks in advance.
Let's consider we have a C++ class:
class iVehicle
{
public:
virtual void Run() {}; // not-pure virtual here for simplicity of a wrapper, but could be pure (see the end of the post)
virtual int GetSize() const; // we want to reuse it in Java
};
We want to create a class Bot in Java that extends class iVehicle in the sense that calls to super invoke the C++ code from iVehicle::GetSize() and, from the C++ point of view, we can use the instances of Bot as iVehicle* variables. That's tough since C++ provides no good built-in functionality for reflection.
Here is one possible solution.
To use C++ class in Java we need to generate a Java wrapper, i.e:
class iVehicle
{
public void Run() { Native_Run(); }
public int GetSize() { return Native_GetSize(); }
private native void Native_Run();
private native int Native_GetSize();
// typecasted to pointer in C++
private int NativeObjectHolder;
// create C++ object
native static private int CreateNativeObject();
}
The usage in Java is simple:
class Bot extends iVehicle
{
public int GetSize()
{
if ( condition ) return 0;
// call C++ code
return super.GetSize();
}
}
However, there is a C++ part to this code:
static jfieldID gNativeObjectHolderFieldID;
JNIEXPORT void JNICALL Java_com_test_iVehicle_Run( JNIEnv* env, jobject thiz )
{
int Value = env->GetIntField(thiz, gNativeObjectHolderFieldID);
iVehicle* Obj = (iVehicle*)Obj;
// todo: add checks here, for NULL and for dynamic casting
Obj->Run();
}
The similar code is for GetSize().
Then creating an instance of Java's Bot you have to call CreateNativeObject() and assign the returned value to the NativeObjectHolder field.
JNIEXPORT int JNICALL Java_com_test_iVehicle_CreateNativeObject( JNIEnv* env, jobject thiz )
{
iVehicle* Obj = new iVehicle;
return (int)Obj;
}
So, this is the scheme. To make this work you will need to add the destruction code and to parse C++ classes to generate all this glue code.
Added:
In case where iVehicle is actually abstract you will have to generate a non-abstract wrapper that you are able to instantiate:
class iVehicle
{
virtual void Run() = 0;
}
class iVehicle_Wrapper: public iVehicle
{
virtual void Run() { ERROR("Abstract method called"); };
}
And instantiate iVehicle_Wrapper in CreateNativeObject(). Vuala! You have inherited an abstract C++ class in Java.
I'm not so familiar with OOP and some things are just too dark for me .
In java ( i'm taking OOP lessons on java but i want to learn C++ ) , i saw that we could define classes on independent files on the same package then use them freely while working on our project .
Is there any equivalent to Java packages in C++ ?? Could i include uniquely defined classes on the source file of the main program ?
Since i'm new to this topic , i beg you to correct me if there's any vocabulary mistake , all i need is knowledge :D Thanx
Since there are those on SO who don't appreciate posting a link, here's the very detailed answer to your question that explains in depth the C++ "equivalent" to Java Packages (Namespaces). If you'd like to view the information in a more readable format, visit the following link:
http://www.cs.sjsu.edu/~pearce/modules/lectures/cpp/advanced/namespaces.htm
Packages in C++: Namespaces
A package is a named collection of declarations that may span several files (see chapter 1). A package defines the scope of the declarations it contains and may be separated into an interface package and an implementation package.
C++ provides several types of scopes: global, file, class, and block. We can also create a package scope using a namespace declaration:
namespace NAME { DECLARATION ... }
References to names outside of their namespace must be qualified using the scope resolution operator. For example, assume a function named jupiter() is declared in a namespace called Planet:[1]
namespace Planet
{
void jupiter() { ... }
// etc.
}
Clients of the Planet namespace must qualify calls to jupiter():
Planet::jupiter();
By contrast:
namespace RomanGods
{
void jupiter() { ... }
// etc.
}
Clients of the RomanGods namespace must qualify calls to jupiter():
RomanGods::jupiter();
All of the declarations in the standard C++ library are contained in a namespace called std. This means names defined in the header file, such as ostream, istream, cout, and cin must be qualified by "std::" when they are used by clients (see Programming Note A.3). For example, here's the official version of the Hello world program:
#include <iostream>
int main()
{
std::cout << "Hello, world!\n";
return 0;
}
We will see how to avoid the std qualifier below.
Example 1: Namespace declarations can span multiple header files
In this example the Car namespace is declared in files ford.h and buick.h:
// ford.h
namespace Car
{
struct Ford
{
void start();
void drive();
void stop();
};
void test(Ford c);
}
// buick.h
namespace Car
{
struct Buick
{
void start();
void drive();
void stop();
};
void test(Buick c);
}
The linker isn't upset by what appears to be two separate declarations of the Car namespace. Instead, it regards the second "declaration" as a continuation of the first.
The implementations are in files ford.cpp and buick.cpp. Notice that the names of the member functions are qualified by the namespace name and the class name:
// buick.cpp
#include "buick.h"
#include <iostream>
void Car::Buick::start() { std::cout << "Starting a Buick\n"; }
void Car::Buick::drive() { std::cout << "Driving a Buick\n"; }
void Car::Buick::stop() { std::cout << "Stopping a Buick\n"; }
void Car::test(Buick c) { c.start(); c.drive(); c.stop(); }
// ford.cpp
#include "ford.h"
#include <iostream>
void Car::Ford::start() { std::cout << "Starting a Ford\n"; }
void Car::Ford::drive() { std::cout << "Driving a Ford\n"; }
void Car::Ford::stop() { std::cout << "Stopping a Ford\n"; }
void Car::test(Ford c) { c.start(); c.drive(); c.stop(); }
The test drivers are declared in file client.cpp:
// client.cpp
#include "ford.h"
#include "buick.h"
test1() uses the qualified names for all items declared in the Car namespace:
void test1()
{
Car::Buick b;
Car::Ford f;
Car::test(b);
Car::test(f);
}
test2() imports the name Car::test into its scope with a using declaration:
void test2()
{
using Car::test;
Car::Buick b;
Car::Ford f;
test(b);
test(f);
}
The using declaration is a bit like an import declaration, but it only allows the unqualified use of the test() functions from the point of the declaration to the end of the scope in which the declaration occurs. In this case the declaration occurs in a block scope. In other words, the test1() function must still qualify calls to test() with "Car::", even if it is declared after test2(). Also notice that we can't import one variant of the test() function but not the other.
test3() imports the entire Car namespace into its scope with the using directive:
void test3()
{
using namespace Car;
Buick b;
Ford f;
test(b);
test(f);
}
Like the using declaration, the using directive only allows unqualified references to namespace names within the scope in which it occurs.
It is common to import the entire std namespace into a file scope to avoid the need to qualify every reference to a library type or object. Here's our new implementation of the Hello world program:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, world!\n";
return 0;
}
This using directive has file scope, which means that standard library names can only be used without qualification within the file.
Example 2: Composition and Selection
Assume FarmJobs and OfficeJobs are namespaces:
namespace FarmJobs
{
void plant() { cout << "planting corn\n"; }
void grow() { cout << "growing corn\n"; }
void pick() { cout << "picking corn\n"; }
}
namespace OfficeJobs
{
void file() { cout << "filing reports\n"; }
void type() { cout << "typing reports\n"; }
void shred() { cout << "shredding reports\n"; }
}
We can create new namespaces from these using composition and selection. Composition creates a namespace by joining several existing namespaces:
namespace Jobs
{
using namespace FarmJobs;
using namespace OfficeJobs;
}
Selection creates a new namespace by selecting items from existing namespaces:
namespace EasyJobs
{
using FarmJobs::grow;
using OfficeJobs::file;
using OfficeJobs::shred;
}
A client can use Jobs and EasyJobs without knowledge of FarmJobs or OfficeJobs:
void test5()
{
Jobs::plant();
Jobs::grow();
Jobs::pick();
Jobs::type();
Jobs::file();
Jobs::shred();
EasyJobs::grow();
EasyJobs::shred();
}
Example 3: Namespaces as Interfaces
Like a header file, a namespace specifies an interface to clients and implementers. The implementer's interface contains all of the declarations:
// register.h
namespace Register // cash register functions
{
void recordItem();
void computeTotal();
void makeReceipt();
void reset();
void lock();
void unlock();
}
As usual, we separate the implementation from the interface:
// register.cpp
#include "register.h"
void Register::recordItem() { ... }
void Register::computeTotal() { ... }
void Register::makeReceipt() { ... }
void Register::reset() { ... }
void Register::lock() { ... }
void Register::unlock() { ... }
Assume we anticipate two types of clients: clerks and managers. Using selection, we can create client interfaces for each one:
// clerk.h
#include "register.h"
namespace ClerkInterface
{
using Register::recordItem;
using Register::computeTotal;
using Register::makeReceipt;
using Register::reset;
}
// manager.h
#include "register.h"
namespace ManagerInterface
{
using Register::unlock;
using Register::lock;
using Register::reset;
}
Example 4: Delegation between Namespaces[2]
We can eliminate the dependency of the manager interface, for example, on the register interface by providing implementations of the manager interface functions that delegate to the corresponding register functions:
// manager.h
namespace ManagerInterface
{
void unlock();
void lock();
void reset();
}
Of course the implementation of the manager interface still depends on the register interface:
// manager.cpp
#include "manager.h"
#include "register.h"
void ManagerInterface::unlock() { Register::unlock(); }
void ManagerInterface::reset() { Register::reset(); }
void ManagerInterface::lock() { Register::lock(); }
I have some code in C and one of the method has a function pointer as argument. I'm trying to use the C code in my Android app.
I decided to use SWIG to do all the work in generating the java files I need. Everything works well with regular function (the one that doesn't have a function pointer as argument).
But I'm not sure how I can pass my JAVA method as a callback to the C function.
Here is an example :
here is my multiply.h file
typedef int (*callback_t) (int a, int b, int c);
int foo(callback_t callback);
here is my multiply.c file
#include <stdio.h>
#include "multiply.h"
int foo(callback_t callback)
{
return callback(2, 4, 6);
}
here is my interface file multiply-swig.i
%module example
%{
/* Includes the header in the wrapper code */
#include "multiply.h"
%}
/* Parse the header file to generate wrappers */
%include "multiply.h"
then I ran the following swig command to generate the java files I need
swig -java -package com.example.ndktest -o multiply-wrap.c mulitiply-swig.i
and then swig generated the following files :
example.java
package com.example.ndktest;
public class example {
public static int foo(SWIGTYPE_p_f_int_int_int__int callback) {
return exampleJNI.foo(SWIGTYPE_p_f_int_int_int__int.getCPtr(callback));
}
}
exampleJNI.java
package com.example.ndktest;
public class exampleJNI {
public final static native int foo(long jarg1);
}
SWIGTYPE_p_f_int_int_int__int.java
package com.example.ndktest;
public class SWIGTYPE_p_f_int_int_int__int {
private long swigCPtr;
protected SWIGTYPE_p_f_int_int_int__int(long cPtr, boolean futureUse) {
swigCPtr = cPtr;
}
protected SWIGTYPE_p_f_int_int_int__int() {
swigCPtr = 0;
}
protected static long getCPtr(SWIGTYPE_p_f_int_int_int__int obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
}
Now how can I call this foo method from my java code? The argument is of type SWIGTYPE_p_f_int_int_int__int ??? I don't understand how I can pass a JAVA method as callback to the C code ... I think I am definitely missing something here ....
Any help is appreciated, thanks
Obviously, you cannot pass a single method as an argument. But callbacks are still possible with "Director" feature via implementing callback in an interface. See this example.
I'm using SWIG to make a Java wrapper of a C++ library (about Json (de)serialization) to use it on Android. I defined an abstract class in C++, representing an object which can be (de)serialized :
class IJsonSerializable {
public:
virtual void serialize(Value &root) = 0;
virtual void deserialize(Value &root) = 0;
};
Now, I'm trying to generate from this class a Java interface. Here's my SWIG interface:
%module JsonSerializable
%{
#include "JsonSerializable.hpp"
%}
%import "JsonValue.i"
class IJsonSerializable {
public:
virtual void serialize(Value &root) = 0;
virtual void deserialize(Value &root) = 0;
};
But the generated Java code is (obviously, as I was not able to find out how to tell SWIG that's an interface) a simple class, with the two methods and a default constructor/destructor:
public class IJsonSerializable {
private long swigCPtr;
protected boolean swigCMemOwn;
public IJsonSerializable(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
public static long getCPtr(IJsonSerializable obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
public synchronized void delete() {
if (swigCPtr != 0) {
if (swigCMemOwn) {
swigCMemOwn = false;
JsonSerializableJNI.delete_IJsonSerializable(swigCPtr);
}
swigCPtr = 0;
}
}
public void serialize(Value root) {
JsonSerializableJNI.IJsonSerializable_serialize(swigCPtr, this, Value.getCPtr(root), root);
}
public void deserialize(Value root) {
JsonSerializableJNI.IJsonSerializable_deserialize(swigCPtr, this, Value.getCPtr(root), root);
}
}
How can I generate a valid interface with SWIG ?
You can achieve what you're looking for with SWIG+Java using "Directors", however it's not quite as straightforward mapping from the C++ abstract classes onto Java as you might hope. My answer therefore is split into three parts - firstly the simple example of implementing a C++ pure virtual function in Java, secondly an explanation of why the output is like that and thirdly a "work-around".
Implementing a C++ interface in Java
Given a header file (module.hh):
#include <string>
#include <iosfwd>
class Interface {
public:
virtual std::string foo() const = 0;
virtual ~Interface() {}
};
inline void bar(const Interface& intf) {
std::cout << intf.foo() << std::endl;
}
We'd like to wrap this and make it work intuitively from the Java side. We can do this by defining the following SWIG interface:
%module(directors="1") test
%{
#include <iostream>
#include "module.hh"
%}
%feature("director") Interface;
%include "std_string.i"
%include "module.hh"
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("module");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. \n" + e);
System.exit(1);
}
}
%}
Here we've enabled directors for the whole module, and then requested they be used for class Interface specifically. Other than that and my favourite "load the shared object automatically" code there's nothing particularly noteworthy. We can test this with the following Java class:
public class Run extends Interface {
public static void main(String[] argv) {
test.bar(new Run());
}
public String foo() {
return "Hello from Java!";
}
}
We can then run this and see it's working as expected:
ajw#rapunzel:~/code/scratch/swig/javaintf > java Run
Hello from Java!
If you're happy with it being neither abstract nor an interface you can stop reading here, directors do everything you need.
Why does SWIG generate a class instead of an interface?
SWIG has however made what looked like an abstract class into a concrete one. That means on the Java side we could legally write new Interface();, which makes no sense. Why does SWIG do this? The class isn't even abstract, let alone an interface (See point 4 here), which would feel more natural on the Java side. The answer is twofold:
SWIG supplies mechanics for calling delete, manipulating the cPtr etc. on the Java side. That couldn't be done in an interface at all.
Consider the case where we wrapped the following function:
Interface *find_interface();
Here SWIG knows nothing more about the return type than that it's of type Interface. In an ideal world it would know what the derived type is, but from the function signature alone there's no way for it to figure this out. This means that in the generated Java somewhere there's going to have to be a call to new Interface, which wouldn't be possible/legal if Interface were abstract on the Java side.
Possible workaround
If you were hoping to provide this as an interface in order to express a type hierarchy with multiple inheritance in Java this would be quite limiting. There's a workaround however:
Manually write the interface as a proper Java interface:
public interface Interface {
public String foo();
}
Modify the SWIG interface file:
Rename the C++ class Interface to be NativeInterface on the Java side. (We ought to make it visible only to the package in question too, with our wrapped code living in a package of its own to avoid people doing "crazy" things.
Everywhere we have an Interface in C++ code SWIG will now be using NativeInterface as the type on the Java side. We need typemaps to map this NativeInterface in function parameters onto the Interface Java interface we added manually.
Mark NativeInterface as implementing Interface to make the Java side behaviour natural and believable to a Java user.
We need to supply a little bit of extra code that can act as a proxy for things which implement the Java Interface without being a NativeInterface too.
What we pass to C++ must always be a NativeInterface still, not all Interfaces will be one though (although all NativeInterfaces will), so we provide some glue to make Interfaces behave as NativeInterfaces, and a typemap to apply that glue. (See this document for a discussion of the pgcppname)
This results in a module file that now looks like:
%module(directors="1") test
%{
#include <iostream>
#include "module.hh"
%}
%feature("director") Interface;
%include "std_string.i"
// (2.1)
%rename(NativeInterface) Interface;
// (2.2)
%typemap(jstype) const Interface& "Interface";
// (2.3)
%typemap(javainterfaces) Interface "Interface"
// (2.5)
%typemap(javain,pgcppname="n",
pre=" NativeInterface n = makeNative($javainput);")
const Interface& "NativeInterface.getCPtr(n)"
%include "module.hh"
%pragma(java) modulecode=%{
// (2.4)
private static class NativeInterfaceProxy extends NativeInterface {
private Interface delegate;
public NativeInterfaceProxy(Interface i) {
delegate = i;
}
public String foo() {
return delegate.foo();
}
}
// (2.5)
private static NativeInterface makeNative(Interface i) {
if (i instanceof NativeInterface) {
// If it already *is* a NativeInterface don't bother wrapping it again
return (NativeInterface)i;
}
return new NativeInterfaceProxy(i);
}
%}
Now we can wrap a function like:
// %inline = wrap and define at the same time
%inline %{
const Interface& find_interface(const std::string& key) {
static class TestImpl : public Interface {
virtual std::string foo() const {
return "Hello from C++";
}
} inst;
return inst;
}
%}
and use it like:
import java.util.ArrayList;
public class Run implements Interface {
public static void main(String[] argv) {
ArrayList<Interface> things = new ArrayList<Interface>();
// Implements the interface directly
things.add(new Run());
// NativeInterface implements interface also
things.add(test.find_interface("My lookup key"));
// Will get wrapped in the proxy
test.bar(things.get(0));
// Won't get wrapped because of the instanceOf test
test.bar(things.get(1));
}
public String foo() {
return "Hello from Java!";
}
}
This now runs as you'd hope:
ajw#rapunzel:~/code/scratch/swig/javaintf > java Run
Hello from Java!
Hello from C++
And we've wrapped an abstract class from C++ as an interface in Java exactly as a Java programmer would expect!