5

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;

これらの 2 つの要素を解析して Java にマップするにはどうすればよいですか? ご意見をお聞かせください。

4

3 に答える 3

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 オブジェクトで利用可能になります。

ご覧のとおり、この場合、追加のネイティブ コードを記述する必要はありません。

JNIWrapperの使用に関する詳細については、そのプログラマー ガイドを参照してください。また、多くの一般的な質問への回答が含まれているJNIWrapper フォーラムもあります。

于 2015-11-09T10:10:32.387 に答える
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データを前後に移動するためのネイティブ メモリの表現だけです。

于 2015-11-06T16:15:18.187 に答える
-1

ああ、ここで長い間検索した後、OOP vs Functional パラダイムに興味を持っています。したがって、ここでは のように解くことができます。基本的な手順は次のとおりです。

  • 構造体に class という名前を付けます。
  • 構造体のすべての属性をクラス属性として配置します。

  • これらの void * については、Java で参照変数を使用できます。

  • 次に、 ipj_iri_device という名前で構造体を取得した構造体インスタンスの場合、箇条書きで名前を付けたクラスのオブジェクトを作成するだけです。

    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 
     }
    
于 2015-11-06T07:47:00.403 に答える