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

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

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

問題描述

限時送ChatGPT賬號..

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

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

我已經(jīng)到了編譯共享庫的地步,一個基本的nfc_version()"方法調(diào)用就可以了.但是,調(diào)用nfc_init()"進(jìn)行設(shè)置會導(dǎo)致 SIGSEGV 錯誤.直接調(diào)用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>

即它應(yīng)該包括 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

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

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).

推薦答案

要始終自動將相同的指針傳遞給函數(shù),這在 SWIG 中相當(dāng)簡單.例如,給定頭"文件 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); }

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

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 設(shè)置一個類型映射,而不是從 Java 中獲取輸入,而是在匹配的任何地方自動調(diào)用 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 開發(fā)人員使用一個健全的接口,但它并不理想:它強(qiáng)制上下文是全局的,這意味著沒有 Java 應(yīng)用程序可以同時使用多個上下文.

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 為我們生成這樣的接口,盡管它有點(diǎn)復(fù)雜.我們的 SWIG 模塊文件變?yōu)?

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"

我們可以成功地運(yùn)行這段代碼:

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

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

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. 接受我們現(xiàn)在可以非常高興地調(diào)用 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 變?yōu)?

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 展示我的上下文結(jié)構(gòu)的真正定義 - 它始終在需要真正定義的任何地方都遵循我的庫",因此不透明指針保持完全不透明.

    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 提供一個僅在包裝器中使用的額外函數(shù):

    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 宏,它比這更面向?qū)ο螅赡苤档檬褂?關(guān)鍵是您提供了工具來處理 SWIG 用來表示它一無所知的指針的不透明指針對象,但避免了本質(zhì)上顛覆類型系統(tǒng)的 getCPtr() 調(diào)用.

    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.

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

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

    Parsing an ISO 8601 string local date-time as if in UTC(解析 ISO 8601 字符串本地日期時間,就像在 UTC 中一樣)
    How to convert Gregorian string to Gregorian Calendar?(如何將公歷字符串轉(zhuǎn)換為公歷?)
    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 日之前日期的日歷到日期轉(zhuǎn)換.公歷到儒略歷切換)
    java Calendar setFirstDayOfWeek not working(java日歷setFirstDayOfWeek不起作用)
    Java: getting current Day of the Week value(Java:獲取當(dāng)前星期幾的值)
    主站蜘蛛池模板: 免费视频99| 中文字幕成人在线 | av激情影院| 毛片久久久| 欧美成人精品激情在线观看 | 欧美精品乱码久久久久久按摩 | 精品久久久久久久 | 一区二区三区四区在线 | 久久久久久久久99 | 国产区一区二区三区 | 精品久久久999 | 亚洲成人蜜桃 | 九九国产在线观看 | cao在线| 中文字幕av在线一二三区 | 国产一区二区日韩 | 精品国产一区二区三区久久 | 欧美一级电影免费观看 | 亚卅毛片 | 久久久精品久 | 97精品一区二区 | 久久美国 | 亚洲福利视频一区二区 | 色婷婷久久久久swag精品 | 亚洲aⅴ精品 | 中文字幕成人av | 国产在线观看福利 | 91中文字幕在线观看 | 国产探花在线精品一区二区 | 亚州春色 | 国内精品伊人久久久久网站 | 久久国产成人 | 亚洲一区中文字幕 | 欧美一级黄色网 | 国产欧美一区二区三区久久手机版 | 中文字幕爱爱视频 | 欧美黄页| 精品欧美一区二区久久久伦 | 91精品国产色综合久久 | www.久久艹 | 亚洲人在线播放 |