I'm using a native library coded in C or C++, after a lot of multiple tests i successed to make it work, but i'm not sure if what i do correspond to the correct coding rules, and some parts are not clear for me.
So my question is : could you confirm and complete what i understood.
Thanks
the C prototype function is:
typedef void (*pfHook) (const char *pText);
and the function to set the callback function is:
short LogHookEx(void (*pfHook) (const char*));
So i created an interface for my native dll like that:
So if i understood "interface pfHookCallback" correspond to the C prototype function and "sCscSetApiLogHookEx" is a classic method from my native dll.
public interface Reader extends Library {
Reader INSTANCE = (Reader) Native.load((Platform.isWindows() ? "ReaderDll" : "c"),
Reader.class);
interface pfHookCallback extends Callback {
void invoke(String pText);
}
short LogHookEx(pfHookCallback pfHook);
}
The part that i understand less, is the part that i include in my "main":
public class Principal {
public static void main(String[] args) {
Reader.pfHookCallback pfHook = new Reader.pfHookCallback() {
public void invoke(String pText) {
System.out.println(pText);
}
};
res = Reader.INSTANCE.LogHookEx(pfHook);
To be more clear this callback function is used for tracing from an hardware device.
As described above, it's working, but it's not cleat for me.
And another question is , the goal of my code is to save the logs (so the pText string) into a file. Is there a best practice to do that, because if i create buffered writer, i don't know if it's good or not to do something like that:
public class Principal {
public static void main(String[] args) {
Reader.pfHookCallback pfHook = new Reader.pfHookCallback() {
public void invoke(String pText) {
bw.write(pText);
bw.close;
}
};
res = Reader.INSTANCE.LogHookEx(pfHook);
My question is i don't know if it's really good to open and close a file very quickly every time there is a log to be saved ?
Related
What is the correct way to map a callback function that has void* as an argument?
I am working with native library (.dll) using JNA.
Library defines the following callback function:
typedef void (__stdcall *NotifyFunc)(int code, void *value);.
Here is how it is mapped in java:
public static NatLib.NotifyFunc notifyFunction = new MyNotifyFuncImpl();
public static void main(String[] args) {
NatLib.INSTANCE.SetCallbackFunc(notifyFunction);
}
public interface NatLib extends Library {
NatLib INSTANCE = Native.load("Nat.dll", NatLib.class);
//...
void SetCallbackFunc(NotifyFunc func);
interface NotifyFunc extends Callback {
void MyNotifyFunc(int code, Pointer value);
}
}
public static class MyNotifyFuncImpl implements NatLib.NotifyFunc {
#Override
public void MyNotifyFunc(int code, Pointer value) {
System.out.println("Notification: " + Integer.toHexString(code));
}
}
I set the callback function. However problems start at runtime. Callback function is executed only once, and then java application fails with non-zero exit value -1073740791. hs_err_pid* log file is not generated.
Is there something wrong with the mapping? I could not find examples for mappings with void* as parameter. Generally void* is mapped as Pointer, is it different when it is used as a parameter?
Do I need to free memory after each callback? I tried to do Native.free(Pointer.nativeValue(value)); inside callback, but this didn't solve the problem.
P.S. I did read JNA - callback method with void* arguments stackoverflow question, but it doesn't seem to be my case. I declared callback as static member public static NatLib.NotifyFunc notifyFunction = new MyNotifyFuncImpl(); - this should keep the reference to callback function unchanged and not garbage collected during runtime.
The problem is that you can not use Callback, if it is a __stdcall function. In this case you need to implement StdCallLibrary.StdCallCallback. So your code should be like this:
interface NotifyFunc extends StdCallLibrary.StdCallCallback{
void MyNotifyFunc(int code, Pointer value);
}
The reason behind this is that __stdcall is used to call functions of the Win32 API. And if you only use Callback Jna does not know it has to use these.
I want to call Linux mount command in java using JNA and populate a list of mount points from the call result but cannot understand what should be the actual return type for the interface method.
If I use int then it prints -1 without any errors. Which I think is an indication of some sort of error.
public class MountTest {
private interface CLibrary extends Library {
String[] mount();
}
public static void main(String[] args) {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
System.out.println(INSTANCE.mount());
}
}
I tried to use different return types based on the below doc but nothing works.
Default Type Mappings
I think my problem is the incorrect signature based on
My library sometimes causes a VM crash: Double check the signature of the method causing the crash to ensure all arguments are of the appropriate size and type. Be especially careful with native pointer variations. See also information on debugging structure definitions.
Could anyone help me on this. What return type should I use so that I can get access to the list of mount points.
Update:
I was able to run a Linux command by tweaking the code as below:
public class MountTest {
private interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
int runCommand(String cmd);
}
public static void main(String[] args) {
CLibrary.INSTANCE.runCommand("mount");
}
}
Now, the problem is, Its printing to the stdout. I don't know how to read the result from stdout using JNA
By mount documentation
mount() attaches the filesystem specified by source (which is often a
pathname referring to a device, but can also be the pathname of a
directory or file, or a dummy string) to the location (a directory or
file) specified by the pathname in target.
It means that mount syscall just mount directories, it's different from the mount command. You are probably looking for getmetent, it will list all your filesystem mount points, a implementation bellow:
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
Pointer fopen(String name, String mode);
Mount.ByReference getmntent(Pointer FILE);
}
public static void main(String[] args) {
final Pointer mountFile = CLibrary.INSTANCE.fopen("/etc/mtab", "r");
if (mountFile == null) {
System.err.println("File not exists: " + mountFile);
return;
}
Mount.ByReference mpoint;
while ((mpoint = CLibrary.INSTANCE.getmntent(mountFile)) != null) {
System.out.println(mpoint);
}
}
public static class Mount extends Structure {
public String mnt_fsname;
public String mnt_dir;
public String mnt_type;
public String mnt_opts;
public int mnt_freq;
public int mnt_passno;
#Override
protected List getFieldOrder() {
List<String> fieds = new ArrayList<>();
for (final Field f : Mount.class.getDeclaredFields()) {
if (!f.isSynthetic())
fieds.add(f.getName());
}
return fieds;
}
public static class ByReference extends Mount implements Structure.ByReference {
}
}
Obs: As I know you cannot call compiled programs from JNA, just library functions and system calls, then is impossible to call mount command, if you really want to use this command then you probably want to use Runtime.getRuntime().exec or something like that.
update
Take a look at this answer there you can differentiate what is a program and what is a syscall or library function
I am developing with GWT and share a codebase with an Android developer. Some functions we want to share take speciffic arguments like "Drawable" under Android and "Image" under GWT.
Is it possible to use a preprocessor variable as in C++:
#ifdef ANDROID
public void DrawImg(Drawable img);
#elif GWT
public void DrawImg(Image img);
#endif
The solution we are testing is a Generic like this:
interface DrawImgInterf<T extends Object> {
public void DrawImg(T img);
}
However using a preproccesor variable seems better. Is there such a thing in Java?
No, there's nothing like that in normal Java. You could run a preprocessor of course, but that will make it painful to develop the code. (Anything like an IDE which expects the code to be "normal" Java is going to get confused.)
Have you considered using an interface instead, which abstracts out the common operations, and binds to the appropriate real type at execution time? That won't always work (as adding a proxy breaks situations where object identity is important) but in some cases it can be helpful.
No, there are no preprocessor variables in Java.
for such cases it is the best way to use a preprocessor
I used it for my J2ME developments http://code.google.com/p/java-comment-preprocessor/wiki/ExampleOfUsageForJ2ME
Java+ is a preprocessor which can perform substitution using resource bundles:
public static void
main(String[] args)
{
System.out.println({{
The answer,
my dearest,
is {{computeAnswer()}}.
}});
}
static String computeAnswer()
{
return {{my computed answer}};
}
References
java+.tgz
java+.dmg
Employing Visitor Pattern here, is making sense to me. For example,
interface ImageVisitor {
void visit(GWTImage image);
void visit(AndroidImage image);
}
interface IImage {
void accept(ImageVisitor visitor);
}
class GWTImage implements IImage {
..
public void accept(ImageVisitor visitor) {
visitor.visit(this);
}
..
}
class AndroidImage implements IImage {
..
public void accept(ImageVisitor visitor) {
visitor.visit(this);
}
..
}
class GWTImageVisitor implements ImageVisitor {
public void visit(GWTImage image) {
Image img = image.getImage();
..
}
}
class AndroidImageVisitor implements ImageVisitor {
public void visit(AndroidImage image) {
Drawable drawable = image.getDrawable();
..
}
}
I compiled following JavaScript file, "test.js", into the "test.class" :
var test = (function () {
var that = {};
that.addNumbers = function (a, b) {
return a+b;
};
return that;
}());
I would like to call the compiled JavaScript function, "test.addNumbers(1,2)", in the simple Java program "run.java" as follows :
public class run {
public static void main(String[] args) throws Exception {
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
// HOW TO CALL THE METHOD, Test.addNumbers(1,2)? Please help me!
} finally {
Context.exit();
}
}
}
I tried many ways, but failed. I read Rhino tutorial and examined many articles and examples, BUT they only show how to call JavaScript methods from the command line or the source file, "test.js".
I need to call the method from the compiled "test.class" file.
Thanks much in advance for your help!
Using javap, I believe that the JavaScript type test does not mean that the resultant Java type is this class. The generated Java type invokes the script code in its constructor; this will not result in exposing addNumbers as a Java method.
>javap -classpath . test
public class test extends org.mozilla.javascript.NativeFunction implements org.m
ozilla.javascript.Script{
public test(org.mozilla.javascript.Scriptable, org.mozilla.javascript.Contex
t, int);
public test();
public static void main(java.lang.String[]);
public final java.lang.Object exec(org.mozilla.javascript.Context, org.mozil
la.javascript.Scriptable);
public final java.lang.Object call(org.mozilla.javascript.Context, org.mozil
la.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])
;
public int getLanguageVersion();
public java.lang.String getFunctionName();
public int getParamCount();
public int getParamAndVarCount();
public java.lang.String getParamOrVarName(int);
public java.lang.String getEncodedSource();
public boolean getParamOrVarConst(int);
}
Reading between the lines, I'd say you need to map to Java types to do what you want. From the jsc doc:
-implements java-intf-name
Specifies that a java class
implementing the Java interface
java-intf-name should be generated
from the incoming JavaScript source
file. Each global function in the
source file is made a method of the
generated class, implementing any
methods in the interface by the same
name.
Define this interface:
//Adder.java
public interface Adder {
public int addNumbers(int a, int b);
}
Write this implementation:
//AdderImpl.js
function addNumbers(a, b) {
return a+b;
}
Compile the JavaScript with the arguments -implements Adder AdderImpl.js. Invoke the method like so:
Adder adder = new AdderImpl();
int n = adder.addNumbers(1, 2);
System.out.println(n);
I'd hazard a guess that it was probably necessary to do it this way because of differences in the languages' type systems.
I used Rhino 1.7R2. For the sake of brevity, I've avoided using packages, etc.
If I have a program that does the following:
if(input=='abc'){do x}
if(input=='def'){do y}
In the future, I may want to add another piece of code like so:
if(input=='ghy'){do x}
As you can see, I am adding a new 'if' statement for a different conditional BUT using the SAME function X.
The code in future has potential to have lots of different IF statements (or switches) all of which are comparing a string vs a string and then performing a function. Considering the future expansion, I was wondering if there is a possible 'neater', 'modular' way of achieving the same results.
It's a shame I can't combine the String with a Method call in a hashtable (String, method) in Java. That way I could just store any new procedures inside a hashtable and grab the relevant method for that String.
Any ideas?
Thank you
EDIT: Thank you for everyone's solutions. I was surprised by the quantity and quality of replies I received in such a small amount of time.
Maybe you can use enum. Example:
public enum InputType
{
abc, def
{
#Override
public void x()
{
System.out.println("Another method");
}
},
ghy;
public void x()
{
System.out.println("One method");
}
}
And further:
InputType.valueOf("abc").x();
Cheers!
I guess you could always use a Map<String, Runnable> and map to anonymous Runnable implementations:
myMap.put("abc", new Runnable() { public void run() { do x } });
...
myMap.get(input).run();
You should take a look at the command pattern. There are several ways of implementing it, and frameworks such as Spring can help you do with in a clean way.
But in a simple manner here's what you could do:
1-Create a Command interface with a method that your program will have to call to do the task, say doTask()
2-Create classes for command X and Y, implementing the Command interface.
3-Create a Map<String, Command> that will map your commands (X and Y) to logical names
4-Create a configuration file of your choice, say a .properties file that will map your input to your command names: abc=X, def=Y, ghi=X
5-Your program then does lookups on the config file to know which command to run according to the input.
A lot of ifs always tell us that we could do this better. In your case better option is to use design pattern e.g. Chain of responsibility. You will have good implementation which you can dynamic change and your code will be easier to maintenance than ifs implementation.
Take a look at this adaptation chain of responsibility to your case:
Main:
public static void main(String[] args) {
ClassA classA = new ClassA(Arrays.asList("abc", "ghi"));
ClassB classB = new ClassB(Arrays.asList("def"));
classA.setNextInChain(classB); // you can always write Builder to do this
String input = "def";
classA.execute(input);
}
BaseClass:
public abstract class BaseClass {
private Collection<String> patterns = Collections.EMPTY_LIST;
protected BaseClass nextInChain;
protected abstract void doMethod(); // your doA, doB methods
public void execute(String input) {
// this replace many ifs in your previous implementation
if (patterns.contains(input)) {
doMethod();
} else {
nextInChain.execute(input);
}
}
public void setPatterns(Collection<String> patterns) {
this.patterns = patterns;
}
public void setNextInChain(BaseClass nextInChain) {
this.nextInChain = nextInChain;
}
}
Class in chain:
public class ClassA extends BaseClass {
ClassA(Collection<String> patterns) {
setPatterns(patterns);
}
#Override
protected void doMethod() {
// do A
}
}
public class ClassB extends BaseClass {...}