Swig generted class in swig interface file - java

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"

Related

How do I "include" code in Java instead of including it in every file? [duplicate]

Coming from a C++ environment I got used to splitting up many of the functions that I needed into an funcs.h file and then do #include "funcs.h" and then adding the functions prototypes into the main .cpp file.
Now I am starting to work with Java (mainly with Minecraft ModloeaderMp), and I already made a funcs.java file where there are some premade functions (e.g., some functions for file copying, giving stacks of items, etc.). Since I am already using the statement Public class mod_mine extends BaseModMp, is there a way I can import the functions or do I can I just do another Public class mod_mine extends funcs?
You don't #include in Java; you import package.Class. Since Java 6 (or was it 5?), you can also import static package.Class.staticMethodOfClass, which would achieve some forms of what you're trying to do.
Also, as #duffymo noted, import only saves you from systematically prefixing the imported class names with the package name, or the imported static method names with the package and class name. The actual #include semantics doesn't exist in Java - at all.
That said, having a "funcs.java" file seems to me like you are starting to dip your toes into some anti-patterns... And you should stay away from these.
There's no #include in Java.
I would not like a design that had a funcs.java that stored all the variables. Objects are state and behavior encapsulated into a single component. You aren't designing in an object-oriented way if you do that.
Good names matter. A class named Stuff that extends Stuff2 had better just be a poor example.
That's not good Java. I wouldn't consider it to be good C++, either.
It sounds like you're putting all your methods in the same class. You should separate them:
Utility classes
These should contain static methods that do things like get the contents of a file, show a dialog screen, or add two numbers together. They don't really belong in an object class, they don't require instances, and they're used widely throughout the program. See java.lang.Math for a good example of this.
Constant class or configuration files
This can be a Constants class that contains static final members, like PI = 3.1415. You can access them using Constants.PI.
Or, you can use configuration files and load them into Configuration and access the configuration variables with something like config.get("database").
Other
If your code doesn't fit into any of these, you will want to put it into some class such that your code fits object-oriented programming concepts. From your question, it sounds like you'll want to read up on this. I would first read Head First Java, then maybe some other books on object-oriented programming in Java. After that, I'd look at some design patterns.
Java is an object-oriented programming language, and there is a reason for it.
There isn't any #include in Java, although you can import classes from other packages.
Making separate class, func.java, to store variables might not be a good idea, until or unless all of them are constants.
By extending some class, you can reuse the function. But does extending class pass the is a test? If not that, this might be a bad idea.
If moving from C++, going through some good book, for example, Head First Java might help a lot.
There isn't any #include in Java. You can use the import statement to make classes and interfaces available in your file.
You can run the C preprocessor on a Java file, ensuring you use the -P flag to disable line annotations. A quick Google search confirms that this has been attempted at least twice, and is even used in the popular fastutil library:
Using C style macros in Java
https://lyubomyr-shaydariv.github.io/posts/2016-09-06-fun-with-java-and-c-preprocessor/
This works for all directives (#include, #define, #ifdef, and so forth) and is both syntactically and semantically identical to the equivalent statements in C/C++.
Actually... There is a way to have the same semantics as in C's #include (the keyword was later borrowed by C++ for the sake of looking fancy...). It's just not defined with the same words, but it does exactly what you are looking for.
First, let's see what you do with #include in C++ to understand the question:
include #defines,
"forward" function definitions (their "body" being defined elsewhere, in a class implementation, if you remember Turbo Pascal, you get my point),
define structures,
and that's pretty much it.
For the structure definitions, there isn't any point. That's old-school C: in C++ you don't define struct {} anymore for ages; you define class structures with properties and accessor methods. It's the same in Java: no typedef struct {} here either.
For this, you have the "interface" declaration (see Interfaces (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)):
It does exactly what you're looking for:
public interface MyDefines {
final CHAR_SPACE : ' '; // ugly #define
int detectSpace(FileInputStream fis); // function declaration
// and so on
}
Then, to use:
public class MyClass extends MyAncestor implements MyDefines {
...
// implementation of detectSpace()
int detectSpace(FileInputStream fis) {
int ret = 0;
char Car;
if((Car = fis.read()) != -1) && (Car == CHAR_SPACE)) ret++;
...
}
Read the link given above; it's full of useful cases.

C++ Function with pointer as parameter and Handle it with swig interface

I have created swig interface file to create JNI for my C++ Files. but some of my C++ Files include functions which accept pointer as argument like (void*) , C++ BOOL and Swig converts it into
type like SWIGTYPE_p_int32_t how to pass such kind of data type from java ?
for example one of the function's actual prototype is like below in C++
DLL_API void DLL_CALLCONV FreeImage_Initialise(BOOL load_local_plugins_only FI_DEFAULT(FALSE));
which is converted in Java file with swig
public static void FreeImage_Initialise(SWIGTYPE_p_int32_t load_local_plugins_only)
how to pass such value from java ?
I have many classes which include such kind of arguments in function.
is there any way so that I can apply solution to bulk files for handle datatype as simple as possible.
I have read one way to do that is create helper function but I cannot go for it because i have many c++ classes and for each and every function creating helper function for returning pointer is not way to go.
Please suggest any other way if possible.
Solved myself. Swig was not be able to recognize all the typedef in header files and hence it was producing that kind of Types in wrapper. I need to redefine them in Interface file.
About booleans, I would recommend using boolinstead of BOOL because JNI directly provides a type signature for it: Z (you can check signatures at: JNI Types and Data Structures)
About pointers, if are pointer to basic types, this is declared by adding [in front of corresponding signature, this is: int* --> [I. If it's a pointer to a own class, swig will create a fully qualified class.
Hope this helps.
This is because of the weird declaration of BOOL type.
In this particular case, you can pass an int there from Java side. Either 0 or 1 will do the right job.
Or you can change BOOL to bool in your native code by creating a small wrapper for this library.
SWIG doesn't know about windows types. Add %include <windows.i> to the interface definition.

Java instantiate C++ class from DLL

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.

Using SWIG to create java bindings for C++ classes

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.

Swig: convert return type std::string to java byte[]

I have a C++ method that returns a std::string. I am using SWIG and I want to add logic to SWIG to make the std::string that is returned, be received in Java as a byte[].
If this is possible, how can I do this?
Thanks
SWIG comes with pre-written interface files for many C++ constructs. The are found in SWIG's Lib directory for many languages, including Java.
Add %include <std_string.i> in your SWIG interface file. Check SWIG's Lib/Java directory for support for other constructs as well.
std::string has a member function c_str that does essentially that. It would probably make sense to write a wrapper function that calls your function and returns the corresponding c string.

Categories

Resources