Java JNA Linkedlist declaration - java

I need to access native C++ code .dll from Java application. native int function works well, but for Linkedlist Struct I cannot find any reference on the Internet how to declare the java interface
this C++ code
struct usb_relay_device_info
{
unsigned char *serial_number;
char *device_path;
usb_relay_device_type type;
usb_relay_device_info* next;
};
int EXPORT_API usb_relay_init(void);
struct usb_relay_device_info EXPORT_API * usb_relay_device_enumerate(void);
int EXPORT_API usb_relay_device_open(struct usb_relay_device_info* device_info);
This is the java part
public interface JNI extends Library {
JNI INSTANCE = (JNI) Native.loadLibrary("usb", JNI.class);
public static class usb_relay_device_info extends Structure {
public static class DeviceInfo extends usb_relay_device_info implements Structure.ByValue {
}
public byte[] serial_number = new byte[1024];
public String device_path;
public int type;
}
int usb_relay_init();
usb_relay_device_info.DeviceInfo usb_relay_device_enumerate();
int usb_relay_device_open(usb_relay_device_info.DeviceInfo deviceInfo);
}
I already created just the struct at the java code (NOT the Linkedlist Struct). So when I call the function the values are not showing up because it supposed to be a list (linkedlist in C++)

You say "I cannot find any reference on the Internet how to declare the java interface" but there are plenty of references, including JNA's Overview, linked to the main project page.
There you will find that char * is a C String and should be mapped to Java's String.
The usb_relay_device_type mapping has to be referenced in the API that you're mapping. In this case it is an enum type, which is an integer, so int is probably appropriate here. (There are cases where it can be a smaller integer value like short or byte but those are rare.)
As for the pointer to the next device, that is also referenced on the overview page under struct*. The link (or explicitly) links to Structure.ByReference. That may not be obvious, but the JNA FAQ, also linked on the main JNA project page, amplifies. If it's still not clear, here's a summary:
By default, Structures listed as fields inside a Structure are treated "By Value", that is, the full structure and its fields are inserted in line. To get this behavior you can simply declare the structure name.
If you want the opposite behavior (By Reference) then you must explicitly state that, and JNA will map a pointer to the structure elsewhere. This is the case you have, and the correct structure mapping is usb_relay_device_info.ByReference. (You'll also need to change the structure declaration to implement ByReference -- the JNA overview, linked above, has an example of this.)
When used in function arguments, such as usb_relay_device_open(), the opposite is true: the "By Reference" is the default, and you only need to explicity specify "By Value" if that's relevant. In this case, it's not -- the native declaration includes the pointer: (usb_relay_device_info*) so you want the ByReference behavior. You can just put usb_relay_device_info device_info there and the ByReference will be implicit. Or, if you prefer (it's not needed) you could do usb_relay_device_info.ByReference device_info and it would just be redundant.
So in summary your structure mapping should be:
class usb_relay_device_info extends Structure {
public static class ByReference extends usb_relay_device_info implements Structure.ByReference { }
public String serial_number;
public String device_path;
public int type;
public usb_relay_device_info.ByReference next;
};
You'll need to add the FieldOrder, preferably using an annotation.

Related

Why doesn't PHP allow class variables to be assigned as objects?

So I have the following question: Why doesn't PHP allow class variable to be instantiated as objects, this is probably the wrong question so I'll show some code to just clarify what I mean.
In java you can do this
private ServerSocket serverSocket;
But in PHP if you try to do something similar like the following
private $var = \MY_CLASS
It will throw a syntax error and you will have to instantiate it through the constructor.
I mean in java you also need to instantiate the variables through the constructor..
Most of the interpreters - including the PHP - is a language with a "free-typed data" (loose typed language):
Strong and weak typing
What is the difference between a strongly typed language and a statically typed language?
It's just one of the approaches to the practice of building language translators.
This does not mean that it is bad. It just means that when designing the architecture of your application, you are taking responsibility for control of the correctness of your data.
But how true it was already mentioned, you may use the annotation mechanism for describing what you want to do
Unfortunately you can only add a phpDoc comment for so that the IDE can help you but you can specify the type (class or array primitive) as arguments for a method
namespace Services;
use Services/SubNamespace/AnotherClass;
class Test
{
/**
* #var AnotherClass
*/
private $property;
public function __construct(AnotherClass $anotherClass){ ... }
public function addVars(array $array){ ... } //You must check your php version to make sure it supports array typehint
}
As an alternative, you could use type hinting comments for your IDE to pickup on, and is just general good practice I feel for PHP code. Here is an example:
<?php
class ExampleClass {
/** #var \MY_CLASS */
private $var;
public function __construct()
{
$this->var = new \MY_CLASS();
}
}
As a general rule for Object Orientation, you should favour dependency injection, rather than instantiating a new object in your class. Eg:
<?php
class ExampleClass {
/** #var \MY_CLASS */
private $var;
public function __construct(\MY_CLASS $var)
{
$this->var = $var;
}
}
$exampleVar = new \MY_CLASS();
$exampleClass = new ExampleClass($exampleVar);

Conditionally inherit from class

I have following class inheritances (A is my parent class):
In some cases, X and Y need some extra fields and methods. So what I basically need is this:
I don't want to extend X and Y to give their child classes exact the same fields and methods due to duplicate code.
How to handle this? Is the only solution a delegate?
Update: Real-world example:
I'm importing data from different file types:
Package my_application.core:
public class ImportFile { // the "A"
protected final Path path;
}
public class CsvImportFile extends ImportFile { // the "X"
private final String delimiter;
}
public class FixedLengthImportFile extends ImportFile { // the "Y"
// nothing new
}
public class XmlImportFile extends ImportFile {
private final String root;
}
Sometimes the first lines of a file contain heads/titles instead of data. So here an example extension which allows to set a start line for csv and fixed-length files:
Package my_application.extension.line_start:
public class ExtensionLineStartImportFile { // the "B"
protected final int lineStart;
// some methods
}
So if the user chooses to use the extension line_start, CsvImportFile and FixedLengthImportFile should get the properties of ExtensionLineStartImportFile.
Side node: Since I have multiple extensions which do different things and these extensions should be easy to add to/remove from the application, I don't want to merge them all into the "core".
Factory pattern - this is quite an architectural issue and this pattern should be the answer for Your problem
You cannot have "conditional inheritance" in Java. Either you extend a class, either you don't. Changing the legacy chain implies recompiling the application.
If a C extends B extends A but B is not on the classpath, the class loading of C will fail.
The only solution I see here is to integrate this logic into your code (or have as many implementations as there are possible combinations).
So, yes, delegates would be a way (probably the only one to have logic on your classpath only when you need it). Having multiple ugly ifs in your code is another.

Loading a static void C function via AndroidfromJNI another Package

I am trying some things out with JNI and by that I found the following problem:
If I want to use a native function in Java I load the needed lib, in which the needed function is stored, via
static{
System.loadLibrary("lib");
}
and use
native private static int calculate(byte[] numberArray);
to declare the native method in the java file. During the program itself I can use this function to calculate something with:
int result = calculate(array);
This works only if I compiled the shared object with the header-file created by javah so that each function is named on c side as:
static void Java_com_packagename_File_calculate(const void* array, void* result){
code[...]
}
If I delete the reference in the java code ("native [...] calculate[...]")to this c function; is there any possibility to access / execute the still existing c-code via java (of course without editing the exisiting file ;-)) for example via reflections or inheritance? Or is there something possible like:
public class NewClass{
public int nativeCheater(){
System.loadLibrary("lib");
native private static int Java_com_packagename_File_calculate;
}
}
It is important that I want to use a whole new class without any relations to the prior used package com.packagename.(File).
Thanks in advance :-)
No, but you can create a new class with same package and class name and access the same native method. The new class can declare this method public.
An alternative is to use dynamic binding via Jni_OnLoad() and RegisterNatives(). This way, your native implementations may bind to any Java class, or even more than one.
But if you have access neither to the Java class nor to the native source, you can always create your own native method, in your own class, and inside your C explicitly call the original:
static void Java_com_mypackagename_File_calculate(const void* array, void* result) {
Java_com_packagename_File_calculate(array, result);
}

JNA direct call not working with argument Structure[]

I have a C++ function:
struct Result {
//...
};
bool doSomething(Result[]);
If I use the following JNA binding, the function call works fine:
public class Result extends Structure {
//...
}
public interface CPPLibrary extends Library {
public static final CPPLibrary INSTANCE = (CPPLibrary)Native.loadLibrary("dllname");
boolean doSomething(Result[]);
}
But with direct call, I hit an IllegalArgumentException saying class [Lcom.usta.Result; is not a supported argument type (in method calcPV01 in class com.usta.CPPLibrary). My JNA code for the direct call-mapping:
public class CPPLibrary implements Library {
Native.register("dllname");
public static native boolean doSomething(Result[]);
}
I can see in com.sun.jna.Function#convertArgument() explicitly handles Structure[] but com.sun.jna.Native#getConversion(), which is used by direct call-mapping, does not handle Structure[].
The conversion is trivial, just call Structure.getPointer() on the first element of your structure array (assuming that you got the array from Structure.toArray in the first place).
You're actually better off with that when using direct mapping; when passing non-primitive, non-pointer types the JNI layer has to call back into the VM to derive the appropriate native data.
Feel free to file an issue for support of Structure[] arguments in direct mappings. That should be supported (JNA documentation notes that arrays of Pointer/String/WString/NativeMapped are not supported).
If I use a different method signature:
boolean doSomething(Pointer results);
it does work. But then I have to convert from Result[] to a Pointer my self.

Checking Inheritance with templates in C++

I've a class which is a wrapper class(serves as a common interface) around another class implementing the functionality required. So my code looks like this.
template<typename ImplemenationClass> class WrapperClass {
// the code goes here
}
Now, how do I make sure that ImplementationClass can be derived from a set of classes only, similar to java's generics
<? extends BaseClass>
syntax?
It's verbose, but you can do it like this:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_base_of.hpp>
struct base {};
template <typename ImplementationClass, class Enable = void>
class WrapperClass;
template <typename ImplementationClass>
class WrapperClass<ImplementationClass,
typename boost::enable_if<
boost::is_base_of<base,ImplementationClass> >::type>
{};
struct derived : base {};
struct not_derived {};
int main() {
WrapperClass<derived> x;
// Compile error here:
WrapperClass<not_derived> y;
}
This requires a compiler with good support for the standard (most recent compilers should be fine but old versions of Visual C++ won't be). For more information, see the Boost.Enable_If documentation.
As Ferruccio said, a simpler but less powerful implementation:
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_of.hpp>
struct base {};
template <typename ImplementationClass>
class WrapperClass
{
BOOST_STATIC_ASSERT((
boost::is_base_of<base, ImplementationClass>::value));
};
In the current state of things, there is no good way other than by comments or a third-party solution. Boost provides a concept check library for this, and I think gcc also has an implementation. Concepts are on the list of C++0x improvements, but I'm not sure if you can specify subtypes - they are more for "must support these operations" which is (roughly) equivalent.
Edit: Wikipedia has this section about concepts in C++0x, which is significantly easier to read than draft proposals.
See Stoustrup's own words on the subject.
Basically a small class, that you instantiate somewhere, e.g. the templated classes constructor.
template<class T, class B> struct Derived_from {
static void constraints(T* p) { B* pb = p; }
Derived_from() { void(*p)(T*) = constraints; }
};

Categories

Resources