久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

使用 SWIG 制作 Java 共享庫的 SIGSEGV 錯誤

SIGSEGV error using SWIG to make a java shared library(使用 SWIG 制作 Java 共享庫的 SIGSEGV 錯誤)
本文介紹了使用 SWIG 制作 Java 共享庫的 SIGSEGV 錯誤的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

限時送ChatGPT賬號..

所以,我正在嘗試使用 SWIG 將 C 庫 (libnfc) 移植到 Java.

So, I'm trying to port a C library (libnfc) to Java using SWIG.

我已經到了編譯共享庫的地步,一個基本的nfc_version()"方法調用就可以了.但是,調用nfc_init()"進行設置會導致 SIGSEGV 錯誤.直接調用nfc庫就可以了.

I've got to the point of having a compiled shared library, and a basic "nfc_version()" method call will work. However, calling "nfc_init()" to set things up causes a SIGSEGV error. Calling the nfc library directly is fine.

我用來生成共享庫的命令:

The commands I used to generate the shared library:

swig -java -I../libnfc/include nfclib.i 
gcc -c -I/usr/lib/jvm/java-7-openjdk-i386/include/ -I/usr/lib/jvm/java-7-openjdk-i386/include/linux nfclib_wrap.c
gcc -shared nfclib_wrap.o ../build/libnfc/libnfc.so libnfc_wrap.so

libnfc.i 文件:

The libnfc.i file:

%module nfc
%{
#include <nfc/nfc.h>
#include <nfc/nfc-types.h>
#include <nfc/nfc-emulation.h>
%}

%include <nfc/nfc.h>
%include <nfc/nfc-types.h>
%include <nfc/nfc-emulation.h>

即它應該包括 libnfc 提供的所有方法.

I.e. it should include all the methods that libnfc provides.

這是我得到的錯誤日志:http://openetherpad.org/AyVDsO4XTg

Here is the error log I am getting: http://openetherpad.org/AyVDsO4XTg

顯然,從我提供的信息中可能無法找到特定的解決方案.但是任何關于嘗試的事情的建議都會非常感激(我在這里的知識已經結束了).

Obviously, it may be that a specific solution may not be available from the information I have provided. But any suggestions of things to try would be really appreciated (I'm sort of at the end of my knowledge here).

推薦答案

要始終自動將相同的指針傳遞給函數,這在 SWIG 中相當簡單.例如,給定頭"文件 test.h,它捕獲了問題的核心部分:

To always pass the same pointer in to a functions automatically it's fairly straightforward in SWIG. For example given the "header" file test.h, which captures the core part of your problem:

struct context; // only used for pointers

void init_context(struct context **ctx) { *ctx=malloc(1); printf("Init: %p
", *ctx); }
void release_context(struct context *ctx) { printf("Delete: %p
", ctx); free(ctx); }

void foo(struct context *ctx) { printf("foo: %p
", ctx); }

我們可以包裝它,并通過執行以下操作自動將全局上下文傳遞到預期的任何地方:

We can wrap it and automatically cause a global context to be passed in everywhere one is expected by doing something like:

%module test

%{
#include "test.h"

// this code gets put in the generated C output from SWIG, but not wrapped:
static struct context *get_global_ctx() {
  static struct context *ctx = NULL;
  if (!ctx) 
    init_context(&ctx);
  return ctx;
}
%}

%typemap(in,numinputs=0) struct context *ctx "$1=get_global_ctx();"

%ignore init_context; // redundant since we call it automatically

%include "test.h"

這會為 struct context *ctx 設置一個類型映射,而不是從 Java 中獲取輸入,而是在匹配的任何地方自動調用 get_global_ctx().

This sets a typemap for struct context *ctx that instead of taking an input from Java automatically calls get_global_ctx() everywhere it matches.

這可能足以讓 Java 開發人員使用一個健全的接口,但它并不理想:它強制上下文是全局的,這意味著沒有 Java 應用程序可以同時使用多個上下文.

That's probably sufficient to make a sane-ish interface for a Java developer to use, however it's less than ideal: it forces the context to be a global and means that no Java application can ever work with multiple contexts at once.

鑒于 Java 是一種 OO 語言,一個更好的解決方案是使上下文成為第一類對象.我們也可以讓 SWIG 為我們生成這樣的接口,盡管它有點復雜.我們的 SWIG 模塊文件變為:

A nicer solution, given that Java is an OO language, is to make the context become a first class Object. We can also make SWIG generate such an interface for us although it's a little more convoluted. Our SWIG module file becomes:

%module test

%{
#include "test.h"
%}

// These get called automatically, no need to expose:
%ignore init_context;
%ignore delete_context;

// Fake struct to convince SWIG it should be an object:
struct context {
  %extend {
    context() {
      // Constructor that gets called when this object is created from Java:
      struct context *ret = NULL;
      init_context(&ret); 
      return ret;
    }
    ~context() {
      release_context($self);
    }
  }
};

%include "test.h"

我們可以成功地運行這段代碼:

and we can exercise this code successfully:

public class run {
  public static void main(String[] argv) {
    System.loadLibrary("test");
    context ctx = new context();
    // You can't count on the finalizer if it exits:
    ctx.delete();
    ctx = null;
    // System.gc() might also do the trick and in a longer
    // running app it would happen at some point probably.
  }
}

給予:

Init: 0xb66dab40
Delete: 0xb66dab40

在動態類型語言中,這將是最難完成的部分——我們可以使用一種或另一種形式的元編程來根據需要插入成員函數.因此,我們可以完全按照預期說出類似 new context().foo(); 的內容.Java 是靜態類型的,所以我們需要更多的東西.我們可以通過多種方式在 SWIG 中執行此操作:

In a dynamically typed language that would be the hard part done - we could use meta programming of one form or another to insert a the member functions as needed. Thus we would be able to say something like new context().foo(); entirely as expected. Java is statically typed though so we need something more. We can do this in SWIG in a number of ways:

  1. 接受我們現在可以非常高興地調用 test.foo(new context()); - 它看起來很像 Java 中的 C,所以我建議它可能是如果你最終編寫了大量看起來像 C 的 Java,代碼味道會很糟糕.

  1. Accept that we can now call test.foo(new context()); quite happily - it looks a lot like C in Java still though so I'd suggest it might be a code smell if you end up writing lots of Java that looks like C.

使用 %extend (手動)將方法添加到上下文類中,test.i 中的 %extend 變為:

Use %extend to (manually) add the methods into the context class, the %extend in test.i becomes:

%extend {
    context() {
      // Constructor that gets called when this object is created from Java:
      struct context *ret = NULL;
      init_context(&ret); 
      return ret;
    }
    ~context() {
      release_context($self);
    }
    void foo() {
      foo($self);
    }
  }

  • %extend 一樣,但在 Java 端使用 typemap 編寫膠水:

  • As with %extend, but write the glue on the Java side, using a typemap:

    %typemap(javacode) struct context %{
      public void foo() {
        $module.foo(this);
      }
    %}
    

    (注意:這需要在接口文件中足夠早才能工作)

    (Note: this needs to be early enough in the interface file to work)

    請注意,我在這里沒有向 SWIG 展示我的上下文結構的真正定義 - 它始終在需要真正定義的任何地方都遵循我的庫",因此不透明指針保持完全不透明.

    Notice that nowhere here have I shown SWIG the real definition of my context struct - it always defers to my "library" for anything where the real definition is required, thus the opaque pointer remains complete opaque.

    用雙指針包裝 init_context 的更簡單的解決方案是使用 %inline 提供一個僅在包裝器中使用的額外函數:

    A simpler solution to wrap the init_context with a double pointer would be to use %inline to provide an extra function that is only used in the wrapper:

    %module test
    
    %{
    #include "test.h"
    %}
    
    %inline %{
      struct context* make_context() {
        struct context *ctx;
        init_context(&ctx);
        return ctx;
      }
    %}
    
    %ignore init_context;
    
    %include "test.h"
    

    足以讓我們編寫如下Java:

    Is sufficient to allow us to write the following Java:

    public class run {
      public static void main(String[] argv) {
        System.loadLibrary("test");
        // This object behaves exactly like an opaque pointer in C:
        SWIGTYPE_p_context ctx = test.make_context();
        test.foo(ctx);
        // Important otherwise it will leak, exactly like C
        test.release_context(ctx);
      }
    }
    

    替代但類似的方法包括使用 cpointer.i 庫:

    Alternative, but similar approaches would include using the cpointer.i library:

    %module test
    
    %{
    #include "test.h"
    %}
    
    %include <cpointer.i>
    
    %pointer_functions(struct context *,context_ptr);
    
    %include "test.h"
    

    然后您可以將其用作:

    public class run {
      public static void main(String[] argv) {
        System.loadLibrary("test");
        SWIGTYPE_p_p_context ctx_ptr = test.new_context_ptr();
        test.init_context(ctx_ptr);
        SWIGTYPE_p_context ctx = test.context_ptr_value(ctx_ptr);
        // Don't leak the pointer to pointer, the thing it points at is untouched
        test.delete_context_ptr(ctx_ptr);
        test.foo(ctx);
        // Important otherwise it will leak, exactly like C
        test.release_context(ctx);
      }
    }
    

    還有一個 pointer_class 宏,它比這更面向對象,可能值得使用.關鍵是您提供了工具來處理 SWIG 用來表示它一無所知的指針的不透明指針對象,但避免了本質上顛覆類型系統的 getCPtr() 調用.

    There's also a pointer_class macro that is a little more OO than that and might be worth using instead. The point though is that you're providing the tools to work with the opaque pointer objects that SWIG uses to represent pointers it knows nothing about, but avoiding the getCPtr() calls which are inherently subverting the type system.

    這篇關于使用 SWIG 制作 Java 共享庫的 SIGSEGV 錯誤的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

    【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!
  • 相關文檔推薦

    Parsing an ISO 8601 string local date-time as if in UTC(解析 ISO 8601 字符串本地日期時間,就像在 UTC 中一樣)
    How to convert Gregorian string to Gregorian Calendar?(如何將公歷字符串轉換為公歷?)
    Java: What/where are the maximum and minimum values of a GregorianCalendar?(Java:GregorianCalendar 的最大值和最小值是什么/在哪里?)
    Calendar to Date conversion for dates before 15 Oct 1582. Gregorian to Julian calendar switch(1582 年 10 月 15 日之前日期的日歷到日期轉換.公歷到儒略歷切換)
    java Calendar setFirstDayOfWeek not working(java日歷setFirstDayOfWeek不起作用)
    Java: getting current Day of the Week value(Java:獲取當前星期幾的值)
    主站蜘蛛池模板: 日本视频免费 | 精品99在线 | 日韩成人中文字幕 | 亚洲一区二区免费视频 | 日韩一区二区在线视频 | 亚洲一级毛片 | 午夜爽爽男女免费观看hd | 国外成人在线视频网站 | 国产做a爱片久久毛片 | 免费观看www7722午夜电影 | www.日日操| 国产视频在线一区二区 | 欧美一区二区在线观看视频 | 欧美一级黄色免费看 | 欧美综合久久久 | h在线播放 | 一区二区av| 99亚洲| 久久视频精品在线 | 国户精品久久久久久久久久久不卡 | 中文字幕视频在线免费 | 黄色av大片 | 国产高清免费视频 | 精品久久国产老人久久综合 | 日本淫视频 | 国产一级片在线观看视频 | 黄色网址免费在线观看 | 福利一区二区 | 日韩一区二区三区四区五区 | 人碰人操 | 999热精品| 精品综合 | 日本成年免费网站 | 羞羞视频在线免费 | 成人影院在线视频 | 精品久久精品 | 欧美激情久久久 | 中文字幕国产精品 | 亚洲成人精品国产 | 日韩成人免费视频 | 久草综合在线 |