JNA : Error when to call natives functions with pointer to struture as parameters - data-structures

I tested this int EMV_Init(EMV_PARAMS *params, EMV_HANDLE *hEMV) in C, it works well.
Now i want to call it in my java application by means of jna. This function is in a native library under windows (dll file).
EMV_PARAMS is a structure
typedef struct
{
HAL_UI_HANDLE ui;
HAL_SCR_HANDLE card;
HAL_PROPERTY_HANDLE property;
HAL_DATE_HANDLE date;
HAL_CRYPTO_HANDLE crypto;
HAL_CHV_HANDLE chv;
} EMV_PARAMS;
Note that all attributes in EMV_PARAMS is is an opaque structure like this typedef void * HAL_UI_HANDLE;
EMV_HANDLE is also an opaque structure : typedef void *EMV_HANDLE;
I need your help to fix the following error:
Exception in thread "main" java.lang.NullPointerException at
com.sun.jna.Structure.getFields(Structure.java:895)
at com.sun.jna.Structure.deriveLayout(Structure.java:1042)
at com.sun.jna.Structure.calculateSize(Structure.java:966)
at com.sun.jna.Structure.calculateSize(Structure.java:933)
at com.sun.jna.Structure.allocateMemory(Structure.java:360)
at com.sun.jna.Structure.<init>(Structure.java:184)
at com.sun.jna.Structure.<init>(Structure.java:172)
at com.sun.jna.Structure.<init>(Structure.java:159)
at com.sun.jna.Structure.<init>(Structure.java:151)
I created a Java interface named "CInterface" which contains "EMV_PARAMS" class.
public interface CInterface extends Library
{
CInterface INSTANCE = (CInterface) Native.loadLibrary("path to dll", CInterface.class);
public int EMVCT_Init(EMV_PARAMS.ByReference params, Pointer hEMV);
public static class PARAMS extends Structure
{
public static class ByReference extends PARAMS implements Structure.ByReference {}
Pointer ui;
Pointer card;
Pointer property;
Pointer date;
Pointer crypto;
Pointer chv;
#Override
protected List getFieldOrder() {
// TODO Auto-generated method stub
return null;
}
}
}
java test class
public static void main(String[] args)
{
CInterface.EMV_PARAMS.ByReference emv_param = new
CInterface.EMV_PARAMS.ByReference();
int test= 0;
Pointer hEMV = null;
test=CInterfaceEMV.INSTANCE.EMVCT_Init(emv_param, hEMV);
System.out.println("test="+test);
}
Thank you for your attention

Your structure fields must be public, and you need to implement getFieldOrder().

Related

Instantiation of virtual member function with templated return type

I have a base class (with which I want to simulate interfaces)
template<typename TType>
class Base
{
public:
virtual SomeTemplatedClass<TType> GetTheObject() = 0;
}
and obviously a derived class
template<typename TType>
class Derived : public Base<TType>
{
public:
virtual SomeTemplatedClass<TType> GetTheObject() = 0;
}
but for some specific type I have the intention to specialize the 'GetTheObject'
template<>
SomeTemplatedClass<int> Derived<int>::GetTheObject()
{
return 5;
}
Visual Studio 2015 complains it cannot instantiate abstract class, when I try to use
Derived<int>
Providing even a throwing behavior to a template version
class Derived : public Base<TType>
{
public:
virtual SomeTemplatedClass<TType> GetTheObject() override
{
throw <something>;
}
}
Let everything compile.
So my question is: Why do i need to provide a generic behavior, when I have a specific one and the only one that is needed?
You don't need to implement the generic GetTheObject, but you need to declare it as non-pure. Otherwise your class is abstract.
template<typename TType>
class Derived : public Base<TType>
{
public:
virtual SomeTemplatedClass<TType> GetTheObject();
}
You can specialise the function now.
You won't be able to instantiate any non-specialised derived objects (you will get linker errors).
You cannot make an abstract class into concrete by simply providing an implementation of its pure virtual member outside of the class.
class A { virtual void f() = 0; }; // A is abstract
void A::f() {} // A is still abstract
Templates are no different.
template <int> class A { virtual void f() = 0; }; // A is abstract
template <int k> void A<k>::f() {} // A is still abstract
A function specialisation changes nothing.
template <int> class A { virtual void f() = 0; }; // A is abstract
template <int k> void A<k>::f() {} // A is still abstract
template <> void A<42>::f() {} // srsly are you kidding?
If you want the generic case to be abstract and the specialised case concrete, you need to specialise the entire class, not just the pure function implementation.

What does ContainingType mean in java method reference

In Java Method References
ContainingClass::staticMethodName - means that a class can refer the static method (Reference to a Static Method )
containingObject::instanceMethodName - means that a class object is created first and then that object is used to refer the instanceMethod .
My doubt is
ContainingType::methodName - what does the ContainingType mean ?
Is ContainingType a predefined class in java like String or something else ?
Java Language Specification, §4.3. Reference Types and Values:
There are four kinds of reference types: class types (§8.1), interface types (§9.1), type variables (§4.4), and array types (§10.1).
Array type don't have static methods, so that doesn't apply to static method reference, but you can do the other 3:
class MyClass {
static void doIt() {/*doing it*/}
}
interface MyInterface {
static void doIt() {/*doing it*/}
}
class Test<T extends MyClass> {
void test() {
Runnable m1 = MyClass::doIt; // class type
Runnable m2 = MyInterface::doIt; // interface type
Runnable m3 = T::doIt; // type variable
}
}
Now that link is provided in a comment, it says:
Reference to a static method
ContainingClass::staticMethodName
Reference to an instance method of a particular object
containingObject::instanceMethodName
Reference to an instance method of an arbitrary object of a particular type
ContainingType::methodName
Reference to a constructor
ClassName::new
Here, again, ContainingType refers to any of the 3 reference types mentioned above: Class, Interface, and Type Variable.
You can then make a method reference for any instance method of such a type.
class MyClass {
void doIt() {/*doing it*/}
}
interface MyInterface {
void doIt();
}
class Test<T extends MyClass> {
void test() {
Consumer<MyClass> m1 = MyClass::doIt;
Consumer<MyInterface> m2 = MyInterface::doIt;
Consumer<T> m3 = T::doIt;
}
}
https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
In the document you gave,there is a example of the ContainingType:
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
and explains:
The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b), where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b).
I think,the element of the stringArray dosen't have a name (eg: String s1 = "Barbara"),so you can't refer it by containingObject::instanceMethodName(eg:s1::compareToIgnoreCase). That's why it uses ContainingType.
I think your ContainingType::methodName is a general/common form of the 2 forms above...
Think about the below code. You can replace the <methodReference> width
InterfaceA::method (for ContainingType::methodName)
ClassA::method (for also ContainingType::methodName)
ClassB::instanceMethod (for ContainingObject::instanceMethodName) or
ClassB::staticMethod (for ContainingClass::staticMethodName)
to demonstrate the mentioned cases:
public class App {
interface InterfaceA {
String method();
}
static class ClassA implements InterfaceA {
public String method() {
return "ContainingType::methodName";
}
}
static class ClassB extends ClassA {
public String instanceMethod() {
return "ContainingObject::instanceMethodName";
}
public static String staticMethod(ClassB classB) {
return "ContainingClass::staticMethodName";
}
}
public static void main(String[] args) {
System.out.println(((Function<ClassB, String>) <methodReference>).apply(new ClassB()));
}
}

Is reference to an instance method serializable in Java 8?

I want to know if reference to an instance method of an arbitrary object of a particular type is serializable or not?
Example:
public class MyClass {
public void foo() {
System.out.println("Serializable");
}
}
SerializableConsumer
#FunctionalInterface
public interface SerializableConsumer<T> extends Consumer<T>, Serializable {
}
and field is:
SerializableConsumer<MyClass> serializableMethod = MyClass::foo;
EDITED
Assuming that SerializableFunction refers to a type that extends Serializable, the method reference will be serializable. There is nothing special about the particular type of method reference your are asking for.
Most notably, the “reference to an instance method of an arbitrary object” is not capturing any instance of MyClass, hence, the fact that MyClass isn’t Serializable is not important. It would be different if you were referring to an instance method of a particular instance like object::foo, as in that case, the object had to be serialized as well, which will fail at runtime, if its class doesn’t implement Serializable.
What will not work, is to refer to a void method as a Function of return type Void. I don’t know how your SerializableFunction<MyClass, Void> is defined, but if it is equivalent to Function<MyClass, Void>&Serializable, it will not work.
When you have an appropriate functional interface, serializing the method reference is no problem:
import java.io.*;
import java.util.function.Consumer;
public class MyClass {
public void foo() {
System.out.println("Serializable");
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Consumer<MyClass> consumer = (Consumer<MyClass>&Serializable)MyClass::foo;
byte[] serialized;
try(ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(consumer);
oos.flush();
serialized=baos.toByteArray();
}
Consumer<MyClass> deserialized;
try(ByteArrayInputStream bais=new ByteArrayInputStream(serialized);
ObjectInputStream ois=new ObjectInputStream(bais)) {
deserialized = (Consumer<MyClass>)ois.readObject();
}
deserialized.accept(new MyClass());
}
}
As said, references to a specific instance have to serialize the target instance, hence, depend on the serializability of that instance so
import java.io.*;
import java.util.function.Consumer;
public class MyClass {
public void foo() {
System.out.println("Serializable");
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Runnable runnable = (Runnable&Serializable)new MyClass()::foo;
byte[] serialized;
try(ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(runnable);
oos.flush();
serialized=baos.toByteArray();
}
Runnable deserialized;
try(ByteArrayInputStream bais=new ByteArrayInputStream(serialized);
ObjectInputStream ois=new ObjectInputStream(bais)) {
deserialized = (Runnable)ois.readObject();
}
deserialized.run();
}
}
will fail at runtime with a java.io.NotSerializableException: MyClass, unless you change MyClass to implement Serializable.
I know you can serialize a lambda expresion (as you can see here)
Now, what you want to do is only serialize a the variable by itself? or the method?... I don't know why, but I don't think you can. Maybe you can go for other way, like creates a lambda and serialize it, like in the post above:
Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!");

Casting an object with events defined to an interface type causes an internal compiler error

I've got an interface with a simple signature:
namespace Serial {
public interface struct ISerial
{
uint16_t func1();
uint16_t func2();
};
}
and then a class type which implements the interface
namespace Serial {
public delegate void MyEventClass();
public ref class MySerial sealed : public ISerial {
public:
event MyEventClass MyEvent;
MySerial();
...
};
}
but elsewhere, as a default parameter to a function, I try to store a reference to a type MySerial as an ISerial ^
void
begin(
Serial::ISerial ^s = ref new Serial::MySerial
);
causes: error C1001: An internal error has occurred in the compiler.
when I remove the event from the class definition, everything compiles fine. I'm finding little information on this error.
I verified this on VS 2013 and it works with a few minor changes (all generated based on normal compiler errors, not an ICE). I don't have VS 2015 available right now, but will log a bug if it still repros.
First the struct (should be unchanged)
namespace Serial
{
public interface struct ISerial
{
uint16_t func1();
uint16_t func2();
};
}
Then the class (couple of changes noted below):
namespace Serial
{
public delegate void MyEventClass();
public ref class MySerial sealed : public ISerial{
public:
event MyEventClass^ MyEvent;
MySerial(){}
virtual uint16_t func1() { return 42; }
virtual uint16_t func2() { return 42; }
};
}
And the usage:
void foo()
{
using namespace Serial;
ISerial^ foo = ref new MySerial();
}
Basically you need to add the hat (^) to the event type, and you need to add virtual to the methods (but do not add override).
See more here on MSDN

c++ cli interface event explicit implementation

I am trying to convert c# code into c++/cli. Everything went smoothly until i started translating interface event explicit implementations into c++/cli syntax.
Let's say in c# i have this interface
public interface Interface
{
public event MyEventHandler Event;
}
Which is implemented in Class in explicit way, so it doesn't conflict with another member by its name:
public interface Class : Interface
{
event MyEventHandler Interface.Event;
public event AnotherEventHandler Event;
}
I am trying to convert Class into c++/cli as follows:
public ref class Class : public Interface
{
virtual event MyEventHandler^ Event2 = Interface::Event
{
}
...
};
This won't compile giving me syntax error in "... = Interface::Event" part. Does anyone have idea what is the right syntax, or does it even exist in c++/cli? I spent some time searching over the Internet, but failed to bump into anything useful.
UPDATE: Here is complete c++/cli code that demonstrates the problem:
public delegate void MyEventHandle();
public delegate void AnotherEventHandle();
public interface class Interface
{
event MyEventHandler^ Event;
};
public ref class Class : public Interface
{
public:
virtual event MyEventHandler^ Event2 = Interface::Event
{
virtual void add(MyEventHandle^) {}
virtual void remove(MyEventHandle^) {}
}
event AnotherEventHandler^ Event;
};
The error output by VC++ 2012 is "error C2146: syntax error : missing ';' before identifier 'MyEventHandler'"
You have to make it look like this:
event MyEventHandler^ Event2 {
virtual void add(MyEventHandler^ handler) = Interface::Event::add {
backingDelegate += handler;
}
virtual void remove(MyEventHandler^ handler) = Interface::Event::remove {
backingDelegate -= handler;
}
};

Resources