我有以下需要映射到Java的C结构。因为我需要从C代码生成的DLL中调用一个方法。以下是我的结构。
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和IPJ_READER_IDENTIFIER如下所示。
typedef void* IPJ_READER_CONTEXT;
typedef void* IPJ_READER_IDENTIFIER;
如何解析这两个元素以映射到Java?请指教。
答案 0 :(得分:0)
以下是使用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];
}
如果您需要其内容,可以定义支持reader_context
和reader_identifier
字段的结构。如果没有,您可以将它们作为通用Pointer
传递。
修改强>
这些结构可以独立于JNA的其余部分使用,您只需要本地内存的Pointer
表示来来回移动数据。
答案 1 :(得分:0)
您可以使用JNIWrapper将C结构映射到Java并从DLL调用该函数。
给定结构的包装器如下所示(需要更改大小常量的值):
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;
}
}
如果需要指向结构实例的指针,则应创建Pointer类实例:
IpjIriDevice structureInstance = new IpjIriDevice();
Pointer structurePtr = new Pointer(structureInstance);
之后,您可以使用指针实例传递函数参数。以下代码演示了如何加载库并从中调用函数:
DefaultLibraryLoader.getInstance().addPath(LIB_PATH);
Library library = new Library(LIB_NAME);
Function function = library.getFunction(FUNCTION_NAME);
long errorCode = function.invoke(returnValue, structurePtr);
如果在调用后修改了结构,则所有更改都将在structureInstance对象中可用。
如您所见,在这种情况下,您无需编写任何其他本机代码。
您可以在programmer's guide中找到有关使用JNIWrapper的更多详细信息。此外,还有JNIWrapper forum包含许多热门问题的答案。
答案 2 :(得分:-1)
Aah经过长时间的搜索,在这里找到了一个关于OOP vs的感兴趣的人 功能范式。 所以在这里我们可以解决它。 这是基本步骤。
将结构的所有属性作为类属性。
对于那些void *,在java中你可以使用引用变量。
然后对于一个结构实例,因为你得到了ipj_iri_device名称的结构,只需创建一个以bullet a命名的类的对象。
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
}