How can I map the following elements of a C structure to Java?

I have the following C structure that needs to be mapped to Java. Because I need to call a method from a DLL generated from C code. Below is my structure.

typedef struct _ipj_iri_device { IPJ_READER_CONTEXT reader_context; IPJ_READER_IDENTIFIER reader_identifier; uint32_t receive_timeout_ms; /* Internal Only */ uint8_t sync_state; bool wait_for_response; uint32_t frame_length; uint32_t receive_index; uint8_t receive_buffer[IPJ_RECEIVE_BUFFER_SIZE]; #if !defined(IRI_RX_ONLY) uint8_t transmit_buffer[IPJ_TRANSMIT_BUFFER_SIZE]; #endif } ipj_iri_device; 

IPJ_READER_CONTEXT and IPJ_READER_IDENTIFIER are as follows.

 typedef void* IPJ_READER_CONTEXT; typedef void* IPJ_READER_IDENTIFIER; 

How can I parse these two elements for mapping with Java? Please advice.

+7
java c jni jniwrapper
source share
3 answers

Here is an example of what your structure looks like with JNA :

 public class ipj_iri_device extends Structure { Pointer reader_context; Pointer reader_identifier; int receive_timeout_ms; /* Internal Only */ byte sync_state; // field size depends on size of 'bool'; "byte" is usually correct byte wait_for_response; int frame_length; int receive_index; byte[] receive_buffer = new byte[IPJ_RECEIVE_BUFFER_SIZE]; // may or may not be used, check your native compile flag byte[] transmit_buffer = new byte[IPJ_TRANSMIT_BUFFER_SIZE]; } 

You can define structures that support the reader_context and reader_identifier if you need their contents. If not, you can simply pass them as a generic Pointer .

EDIT

These structures can be used independently of the rest of the JNA, all you need is a Pointer representation of the internal memory to move data back and forth.

0
source share

You can use JNIWrapper to map a C structure to Java and call a function from a DLL.

The shell for this structure will look as shown below (values ​​for the size constants need to be changed):

 import com.jniwrapper.*; public class IpjIriDevice extends Structure { private static final int IPJ_RECEIVE_BUFFER_SIZE = 0; private static final int IPJ_TRANSMIT_BUFFER_SIZE = 0; private Pointer.Void reader_context = new Pointer.Void(); private Pointer.Void reader_identifier = new Pointer.Void(); private UInt32 receive_timeout_ms = new UInt32(); private UInt8 sync_state = new UInt8(); private Bool wait_for_response = new Bool(); private UInt32 frame_length = new UInt32(); private UInt32 receive_index = new UInt32(); private PrimitiveArray receive_buffer = new PrimitiveArray(UInt8.class, IPJ_RECEIVE_BUFFER_SIZE); private PrimitiveArray transmit_buffer = new PrimitiveArray(UInt8.class, IPJ_TRANSMIT_BUFFER_SIZE); public IpjIriDevice() { init(new Parameter[] { reader_context, reader_identifier, receive_timeout_ms, sync_state, wait_for_response, frame_length, receive_index, receive_buffer, transmit_buffer }); } public long getReaderContext() { return reader_context.getValue(); } public long getReaderIdentifier() { return reader_identifier.getValue(); } public long getReceiveTimeoutMs() { return receive_timeout_ms.getValue(); } public void setReceiveTimeoutMs(long value) { receive_timeout_ms.setValue(value); } public long getSyncState() { return sync_state.getValue(); } public void setSyncState(long value) { sync_state.setValue(value); } public boolean getWaitForResponse() { return wait_for_response.getValue(); } public void setWaitForResponse(boolean value) { wait_for_response.setValue(value); } public long getFrameLength() { return frame_length.getValue(); } public void setFrameLength(long value) { frame_length.setValue(value); } public long getReceiveIndex() { return receive_index.getValue(); } public void setReceiveIndex(long value) { receive_index.setValue(value); } public PrimitiveArray getReceiveBuffer() { return receive_buffer; } public PrimitiveArray getTransmitBuffer() { return transmit_buffer; } public Object clone() { IpjIriDevice result = new IpjIriDevice(); result.initFrom(this); return result; } } 

If you need a pointer to an instance of the structure, you must create an instance of the pointer class:

 IpjIriDevice structureInstance = new IpjIriDevice(); Pointer structurePtr = new Pointer(structureInstance); 

After that, you can use the pointer instance to pass the parameter to the function. The following code demonstrates how to load a library and call a function from it:

 DefaultLibraryLoader.getInstance().addPath(LIB_PATH); Library library = new Library(LIB_NAME); Function function = library.getFunction(FUNCTION_NAME); long errorCode = function.invoke(returnValue, structurePtr); 

If the structure is changed after the call, all changes will be available in the structureInstance object.

As you can see, in this case you do not need to write additional native code.

More information on using JNIWrapper can be found in the programmer's guide . In addition, there is a JNIWrapper forum containing answers to many popular questions.

0
source share

Aah, after a long search, he is interested in OOP versus Functional Paradigm. So, we can solve it as. Here are the basic steps.

  • Name your structure as a class.
  • Place all structure attributes as class attributes.

  • For these void * in java, you can use reference variables.

  • then for an instance of the structure, when you have a structure called ipj_iri_device, just create a class object with a name in the pool.

     public class _ipj_iri_device{ int IPJ_RECEIVE_BUFFER_SIZE ; //get a value from whereever the input is coming ,assign it to buffersize IPJ_READER_CONTEXT reader_context; IPJ_READER_IDENTIFIER reader_identifier; boolean wait_for_response; uint32_t receive_timeout_ms; //here uint32_t is a type i asumed .You will have to define it explicitly //rest of the vaariables / members of structure } 
-one
source share

All Articles