簡體   English   中英

回調作為C結構的參數 - Java包裝器生成

[英]Callback as parameter of C structure - Java wrapper generation

感謝@flexo ,當自由函數作為參數傳遞給另一個函數時,我對簡單的回調沒有任何問題。

但假設C接口比較困難:

typedef struct
{
    int id;
    const char* name;
} Item;

typedef struct
{
    int value;
    Items_Callback callback;
    void *context;
} Items_Call;

typedef int (*Items_Callback)(const Item *item, void *context);

int Items_create(const Item *item, Items_Call *call) {
  ...
  call->callback(item, call->context);
  ...
}

我打算為這樣的代碼生成一些不錯的Java包裝器。 我假設有結果

class Item {
  public int id;
  public String name;
}

class Items_Call {
  public int value;
  public Object context;
  public Interface callback;
  public void setInterface(Interface i){ callback=i; };
}

public interface Interface {
  public int Items_Callback(Item item, Object context);
} 

int Items_create(Item item, Items_Call call) {
  ...
  call.callback.Items_Callback(item, call.context);
  ...
}

我意識到SWIG在生成純Java接口方面存在一些問題,但我認為這不是主要問題。 問題是我不知道如何將這種嵌套結構重新解釋為可接受的Java代碼。

不是SWIG,但以下適用於JavaCPP (它沒有JNA的那種開銷,並且適用於JNI工作的任何地方):

// items.h
typedef struct
{
    int id;
    const char* name;
} Item;

typedef int (*Items_Callback)(const Item *item, void *context);

typedef struct
{
    int value;
    Items_Callback callback;
    void *context;
} Items_Call;

int Items_create(const Item *item, Items_Call *call) {
//  ...
    call->callback(item, call->context);
//  ...
    return 0;
}

在Java中:

import com.googlecode.javacpp.*;
import com.googlecode.javacpp.annotation.*;

@Platform(include="items.h")
public class Items {
    static { Loader.load(); }

    public static class Item extends Pointer {
        public Item() { allocate(); }
        private native void allocate();

        public native int id();           public native Item id(int id);
        @Cast("const char*")
        public native BytePointer name(); public native Item name(BytePointer name);
    }

    public static class Items_Callback extends FunctionPointer {
        protected Items_Callback() { allocate(); }
        private native void allocate();

        public native int call(@Const Item item, Pointer context);
    }

    public static class Items_Call extends Pointer {
        public Items_Call() { allocate(); }
        private native void allocate();

        public native int value();               public native Items_Call value(int value);
        public native Pointer context();         public native Items_Call context(Pointer context);
        public native Items_Callback callback(); public native Items_Call callback(Items_Callback value);

        public void setInterface(Items_Callback i) { callback(i); }
    }

    public static native void Items_create(Item item, Items_Call call);

    public static void main(String[] args) {
        BytePointer s = new BytePointer("Hello");
        Item i = new Item();
        i.id(42);
        i.name(s);

        Items_Callback cb = new Items_Callback() { 
            public int call(Item item, Pointer context) {
                System.out.println(item.id() + " " + item.name().getString());
                return 0;
            }
        };
        Items_Call ic = new Items_Call();
        ic.callback(cb);

        Items_create(i, ic);

        // if we remove these references, the GC may prematurely deallocate them
        s.deallocate();
        cb.deallocate();
    }
}

哪個輸出預期結果:

42 Hello

免責聲明:我是JavaCPP的作者:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM