Use custom creator and deleter for C structure - java

I have on C side
typedef struct {} C_String;
C_String* StringNew();
void StringFree(C_String* string);
On Java I get such wrapper class
public class String {
private long swigCPtr;
protected boolean swigCMemOwn;
protected String(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
protected static long getCPtr(String obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
public synchronized void delete() {
if (swigCPtr != 0) {
if (swigCMemOwn) {
swigCMemOwn = false;
JNI.delete_C_String(swigCPtr);
}
swigCPtr = 0;
}
}
public String() {
this(JNI.new_C_String(), true);
}
}
JNI.new_С_String and JNI.delete_С_String are native methods generated by SWIG, they do simple work - allocate C_String by malloc and delete it by free respectively. In my case scenario should be different, since C_String is empty structure and acts like shortcut proper way should be allocation by StringNew which has malloc under hood and freeing by StringFree.
I want to use proper methods instead of JNI.new_String, JNI.delete_String what the easiest method to achieve this?

Assuming the C you showed is in a file called test.h the following SWIG interface would do what you wanted:
%module test
%{
#include "test.h"
%}
%extend C_String {
C_String() {
return StringNew();
}
~C_String() {
StringFree($self);
}
}
%ignore StringNew;
%ignore StringFree;
%include "test.h"
This uses %extend to supply a custom constructor and destructor for the C_String type. This constructor/destructor pair just calls the C functions StringNew and StringFree respectively.
In your question you asked to have these calls happen from within the generated Java code. The way I've written it above makes these calls happen from within C instead. This has two primary benefits:
It is language neutral - the same interface file works equally well regardless of what language you're targeting.
It minimses calls between native and Java (or any other target) code. This is generally a good thing from a performance perspective since these cross-language jumps tend to be the most expensive part of your interface.
The remainder of this answer is mostly just here as a learning point and not a recommended solution.
If you really wanted to though you could write this as Java and make the JNI calls you asked for. To do this you would need to write a few typemaps, you would need at least two which (untested) might look something like:
javabody:
%typemap(javabody) C_String %{
private long swigCPtr;
protected boolean swigCMemOwn;
protected $javaclassname(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
public $javaclassname() {
$javaclassname tmp = $imclassname.StringNew();
swigCMemOwn = tmp.swigCMemoryOwn;
swigCPtr = tmp.swigCPtr;
tmp.swigCMemoryOwn = false;
}
protected static long getCPtr($javaclassname obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
%}
javadestruct:
%typemap(javabody) C_String %{
public synchronized void delete() {
if (swigCPtr != 0) {
if (swigCMemOwn) {
swigCMemOwn = false;
$imclassname.StringFree(swigCPtr);
}
swigCPtr = 0;
}
}
%}
But as noted previously this really isn't the best way to solve the problem. (You'd need a 'javadestruct_derived' typemap as well if you wanted this to still happen for cases with inheritance)

Related

Using std::vector in Java with SWIG

I'm new to this SWIG thing and the interaction between Java and C++.
I'm trying using pjsip library wrapped with Java.
i have the following structure in a file called "call.hpp":
/**
* This structure contains parameters for Call::onCreateMediaTransportSrtp()
* callback.
*/
struct OnCreateMediaTransportSrtpParam
{
/**
* The media index in the SDP for which the SRTP media transport
* will be used.
*/
unsigned mediaIdx;
/**
* Specify whether secure media transport should be used. Application
* can modify this only for initial INVITE.
* Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and
* PJMEDIA_SRTP_MANDATORY.
*/
pjmedia_srtp_use srtpUse;
/**
* Application can modify this to specify the cryptos and keys
* which are going to be used.
*/
vector<SrtpCrypto> cryptos;
};
now, this how the Java wrapper for this function looks like(i've omitted some getters and setters to reduce length):
package org.pjsip.pjsua2;
public class OnCreateMediaTransportSrtpParam {
private transient long swigCPtr;
protected transient boolean swigCMemOwn;
protected OnCreateMediaTransportSrtpParam(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
protected static long getCPtr(OnCreateMediaTransportSrtpParam obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
public synchronized void delete() {
if (swigCPtr != 0) {
if (swigCMemOwn) {
swigCMemOwn = false;
pjsua2JNI.delete_OnCreateMediaTransportSrtpParam(swigCPtr);
}
swigCPtr = 0;
}
}
public void setCryptos(SWIGTYPE_p_vectorT_pj__SrtpCrypto_t value) {
pjsua2JNI.OnCreateMediaTransportSrtpParam_cryptos_set(swigCPtr, this, SWIGTYPE_p_vectorT_pj__SrtpCrypto_t.getCPtr(value));
}
public SWIGTYPE_p_vectorT_pj__SrtpCrypto_t getCryptos() {
long cPtr = pjsua2JNI.OnCreateMediaTransportSrtpParam_cryptos_get(swigCPtr, this);
return (cPtr == 0) ? null : new SWIGTYPE_p_vectorT_pj__SrtpCrypto_t(cPtr, false);
}
public OnCreateMediaTransportSrtpParam() {
this(pjsua2JNI.new_OnCreateMediaTransportSrtpParam(), true);
}
}
now, i don't know how to use setCryptos with the SWIGTYPE_p_vectorT_pj__SrtpCrypto_t type in the parameter.
i've trying the following:
SrtpCrypto crypto = new SrtpCrypto();
crypto.setName("AES_CM_128_HMAC_SHA1_80");
OnCreateMediaTransportSrtpParam prm = new OnCreateMediaTransportSrtpParam();
Vector<SrtpCrypto> cryptos = new Vector<SrtpCrypto>();
cryptos.add(crypto);
prm.setCryptos(cryptos);
but i get the following error:
error: incompatible types: Vector<SrtpCrypto> cannot be converted to SWIGTYPE_p_vectorT_pj_SrtpCrypto_t
any ideas on how to proceed?
Thank you very much!!!
From what you've shown there's a mismatch between the types SWIG sees and the types being used.
In call.hpp you have:
vector<SrtpCrypto>
This vector here is almost certainly one from namespace std, which you've told SWIG to wrap, but here because of namespace directives of some sort that you've not shown it the question SWIG hasn't realised they're the same type, and used a default opaque type instead which isn't interchangable.
The simplest fix is for you to change your header file to say:
std::vector<SrtpCrypto>
instead then the error will almost certainly go away.

Maintaining state in SWIG Java director class

I want to access a Java graph library (Titan) from c++. Doing some research showed that JNI would get the job done. I wrote some JNI code, got it working, but it quickly became tedious, so I looked to an automated solution. I found SWIG, more specifically SWIG directors. I have no problem calling functions, however I have a problem of maintaining state going back and forth from Java and c++ using a SWIG director.
For my SWIG directors I wrote c++ interfaces exposing the functionality I wanted. Below is a sample:
GraphIfc.hpp:
struct GraphIfc {
virtual ~GraphIfc() {}
virtual VertexIfc * addVertex(const std::string& label) = 0;
};
VertexIfc.hpp:
struct VertexIfc {
virtual ~VertexIfc() {}
virtual EdgeIfc * addEdge(const std::string& label, VertexIfc * v) = 0;
};
EdgeIfc.hpp:
struct EdgeIfc {
virtual ~EdgeIfc() {}
};
Then I wrote the Java implementation:
JGraph.java:
import com.thinkaurelius.titan.core.TitanGraph;
public class JGraph extends GraphIfc {
private TitanGraph graph;
public JGraph(TitanGraph g) {
graph = g;
}
public VertexIfc addVertex(final String label) {
return new Vertex(graph.addVertex(label));
}
}
JVertex.java:
import com.thinkaurelius.titan.core.TitanVertex;
public class JVertex extends VertexIfc {
public TitanVertex vertex;
public JVertex(TitanVertex v) {
vertex = v;
}
public EdgeIfc addEdge(final String label, VertexIfc inV) {
Vertex v = (Vertex)inV;
return new Edge(vertex.addEdge(label, v.vertex));
}
}
JEdge.java:
import org.apache.tinkerpop.gremlin.structure.Edge;
public class JEdge extends EdgeIfc {
public Edge edge = null;
public JEdge(Edge e) {
edge = e;
}
}
And here's my SWIG file:
%module(directors="1") graph
%{
#include "graph.hpp"
#include "vertex.hpp"
#include "edge.hpp"
%}
%feature("director") GraphIfc;
%feature("director") VertexIfc;
%feature("director") EdgeIfc;
SWIG_DIRECTOR_OWNED(GraphIfc)
SWIG_DIRECTOR_OWNED(VertexIfc)
SWIG_DIRECTOR_OWNED(EdgeIfc)
%include "graph.hpp"
%include "vertex.hpp"
%include "edge.hpp"
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("graph");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library graph failed to load.\n" + e);
System.exit(1);
}
}
%}
All of this produces:
Java proxy classes: GraphIfc, VertexIfc, EdgeIfc. These hold the c++ pointer as a long.
Intermediary JNI class in Java with functions
such as:
public static long SwigDirector_GraphIfc_addVertex(GraphIfc jself, String label) {
return VertexIfc.getCPtr(jself.addVertex(label));
}
public static long SwigDirector_VertexIfc_addEdge(VertexIfc jself, String label, long inVertex) {
return EdgeIfc.getCPtr(jself.addEdge(label, (inVertex == 0) ? null : new VertexIfc(inVertex, false)));
}
There are a two problems with these functions:
The VertexIfc being created by SwigDirector_VertexIfc_addEdge is not of type JVertex, thus my cast within addEdge will fail and throw an exception.
But more importantly, even if the type was a JVertex, the new JVertex would not contain the same value of TitanVertex as set by addVertex. Any state within the derived class (JVertex, JEdge, etc) is loss.

Call a method based on the object type

I have two helper methods:
public String load(URL url) {...}
public String load(File file) {...}
I want to have a method that calls the appropriate helper method depending on what object type it receives:
public void operate(Object object) {...}
I understand that there is a convoluted way of doing it which is:
public void operate(Object object) {
String data = null;
if (object.getClass().equals(File.class)) {
data = load((File) object);
}
if (object.getClass().equals(URL.class)) {
data = load((URL) object);
}
// operate on the data....
}
However, this does not seem elegant and was curious if there was a better way..
However, this does not seem elegant and was curious if there was a better way.
That's right. This violates the Open-Closed principle. A class must be open to extension but closed to modification. You are also correct when you say that you need a generic Object. Here's what you can do :
Create a Loader interface
public interface Loader<T> {
public String load(T t);
}
Create a loader for loading from File
public class FileLoader implements Loader<File> {
public String load(File f) {
//load from file
}
}
Create a loader for loading from Url
public class UrlLoader implements Loader<Url> {
public String load(URL r) {
//load from url
}
}
Create a class that operates on the data
class DataOperator<T> {
Loader<T> loader;
public SomeClient(Loader<T> loader) {
this.loader = loader;
}
public void operate(T inputSource) {
String data = loader.load(inputSource);
//operate on the data
}
}
Client code can then use the above API as shown below :
DataOperator<File> fileDataOperator = new DataOperator<>(new FileLoader());
fileDataOperator.operate(new File("somefile.txt"));
DataOperator<URL> urlDataOperator = new DataOperator<>(new UrlLoader());
urlDataOperator.operate(new URL("http://somesite.com"));
You might be thinking that this is a lot of classes for solving a simple problem. However, this is actually inline with the well known Open-Closed design principle. Notice how you control what technique is used for loading the data by creating an instance of an appropriate class. Another advantage you get is that you can decide which technique to use at runtime by creating a Factory that takes user input and creates the appropriate concrete subclass. This is a simplified version of the Strategy pattern.
Disclaimer : The code samples presented above have not been tested for compilation errors as I don't have Java on this machine.
A slightly less convoluted way is instanceof, e.g.
if (object instanceof File)) {
data = load((File) object);
}
However, most of the time, using instanceof is a sign that there's a better structure for what you're trying to achieve, e.g.
public void operate(File file) {
operate(load(file));
}
public void operate(URL url) {
operate(load(url));
}
public void operate(String data) {
// operate on the data....
}
You can use instanceof and check it and then cast the object and call the method:
if (obj instanceof File) {
((File) obj).method();
}
else if (obj instanceof URL) {
((URL) obj).method();
}
or the inverse like:
if (obj instanceof File) {
load((File) obj)
}
else if (obj instanceof URL) {
load((URL) obj)
}
You're correct: casting is necessary but inelegant.
Another way to do this if you like GoF Design Patterns is the Visitor pattern aka double dispatch.
A third way is to use Java reflection.
I just stumbled on the same problem and found a different approach using Reflection:
public void operate(Object object) {
Method method = this.getClass().getDeclaredMethod("load", object.getClass());
String data = (String) method.invoke(this, object);
// [...]
}
Of course, it comes with the burden of handling quite a few exceptions.
Overload the operate-method as well. The use the data which you received to call a method which accepts an String.
public static void operate(URL url) {
String data = load(url);
doOperations(data);
}
public static void operate(File file) {
String data = load(file);
doOperations(data);
}
private static void doOperations(String data) {
//TODO Do something with data
}

how to use SWIGTYPE_p_CHAR class in my main class?

I have used typemaps :
%include "typemaps.i"
%apply SWIGTYPE * {char *deci};
This is the proxy class generated by SWIG:
public class SWIGTYPE_p_char {
private long swigCPtr;
protected SWIGTYPE_p_char(long cPtr, boolean futureUse) {
swigCPtr = cPtr;
}
protected SWIGTYPE_p_char() {
swigCPtr = 0;
}
protected static long getCPtr(SWIGTYPE_p_char obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
}
it seems trivial, but have you tried:
SWIGTYPE_p_char my_p_char;
after all, all that the class contains is a long int representation of the pointer address
clearly you can only use this for a c function that returns a char* or uses a char* parameter as a pseudo return value
if you want to use a char* input parameter then you'll most likely have to write a helper function of some sort
I wrapped this function prototype with SWIG recently:
int load_config(const char *fn, Config *cfg);
which loaded data into my Config data-structure from a file specified by a string (char*)
I was able to call it from Java with the following line:
example.load_config("test.cfg", cfg);
or alternatively:
String cfg_file = "test.cfg";
example.load_config(cfg_file, cfg);

How can I implement a lazy-evaluated stateful class with internal dependencies in Java?

I'm writing a financial calculation class which will have a number of setter function inputs, some private intermediate values and a number of getter functions as outputs.
The private intermediate values are only dependant on the input values.
The output values (accessed by public getters) are only dependant on the inputs and the intermediate values.
Ultimately you could draw the whole thing as a somewhat tangled acyclic directed graph whith a bunch of inputs on one side, eventually flowing to a bunch of outputs on the right hand side.
What's the best way to implement this class. I have some spesific requirements:
Where possible, lazy evaluate. When an input changes we have now way of knowing what outputs might be required.
The class has to be easy to re-design, so some kind of declarative model would epreferred.
Ideally I'd like to be able to say that C depends on A and B. If C were requested after either A or B had changed then it would know tht C needed to be re-calculated, otherwise C would never need to be refreshed.
IIs there a Java pattern that might help me cleanly implement this kind of calculator?
You can build a solution by creating a future value that is recalculable.
public class Computation<T> {
private T value;
private Set<Computation<?>> usedBy;
public T getValue(Computation<?> getter) {
if (usedBy == null) {
// value was not computed
value = compute();
usedBy = new HashSet();
}
if (getter != null) {
// add a dependency
usedBy.add(getter);
}
return value;
}
protected T compute() {
// override when needed a lazily-computed value
return null;
}
public void setValue(T value) {
// invalidate this value
invalidate();
// set the new value
this.value = value;
usedBy = new HashSet();
}
public void invalidate() {
if (usedBy != null) {
for (Computation<?> c : usedBy) {
c.invalidate();
}
usedBy = null;
}
value = null;
}
}
public class Business {
private Computation<Integer> a = new Computation<Integer>();
private Computation<Integer> b = new Computation<Integer>();
private Computation<Integer> c = new Computation<Integer>() {
public Integer compute() {
return a.getValue(this) + b.getValue(this);
}
};
public void setA(int v) {
a.setValue(v);
}
public void setB(int v) {
b.setValue(v);
}
public int getC() {
return c.getValue(null);
}
}
It is completely lazy and figures out the dependencies.
You can use a pattern like this.
double[] inputs = { ... }
double[] previousInputs = { Double.NaN, etc }; // NaN is never equal.
double[] outputs =
public void update() {
if (!Arrays.equals(inputs, previousInputs)) {
recalculate(inputs, outputs);
copyTo(inputs, previousInputs);
}
}
Seems like you have some sort of real-time stream processing problem.
Take a look at twitter storm. Even if you decide not to use it you can borrow some concepts explained at tutorial page.
Personally I agree with Peter but for arguments sake I have two other answers. I would recommend looking at a rules engine (e.g. Drools) for implementing flexible business logic like this. They are designed so that the rules for updates between variables are easy to set and change at will. They should also be fairly performant.
Then, for the DYI-er, here is a Spring inspired version. The biggest drawback is that you get your dependencies as a list. You could easily use a HashMap but then you'd lose your syntax-safety.
public abstract class Variable<T> {
private T currentValue;
private List<Variable<?>> dependencies = new ArrayList<Variable<?>>();
private List<Variable<?>> upstream = new ArrayList<Variable<?>>();
public T get() {
return currentValue;
}
public void set(T newValue) {
currentValue = newValue;
updateUpstream();
}
public abstract T recalculateValue(List<Variable<?>> dependencies);
private void update() {
set(recalculateValue());
}
private void updateUpstream() {
for(Variable<?> variable : upstream) {
variable.update();
}
}
private void addUpstream(Variable<?> variable) {
upstream.add(variable);
}
public void setDependencies(List<Variable<?>> dependencies) {
this.dependencies = dependencies;
for(Variable<?> variable) {
variable.addUpstream(this);
}
}
}
The corresponding applicationContext.xml would look like:
<bean id="A" class="com.app.AVariable"/>
<bean id="B" class="com.app.BVariable"/>
<bean id="C" class="com.app.CVariable">
<property name="dependencies">
<list>
<ref bean="A"/>
<ref bean="B"/>
</list>
</property>
</bean>
For extra credit you could implement a bean post-processor to calculate and set the dependencies automatically based on annotations. For example:
public class CVariable extends Variable<Integer> {
private AVariable a;
private BVariable b;
#Dependency
public void setA(AVariable a) {
this.a = a;
}
#Dependency
public void setB(BVariable b) {
this.b = b;
}
//If you were going this route you wouldn't need the list of dependencies
public Integer recalculateValue() {
return a.get() + b.get();
}
}

Categories