質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

C++で作成した共有ライブラリ(so)をJava(JNA)で参照しようとしたが、「undefined symbol (未定義のシンボル)」で失敗します。

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 208

fuoh

score 19

C++で作成した共有ライブラリ(so)をJNAを利用してJavaプログラムで参照しようとしましたが、
「undefined symbol (未定義のシンボル)」で失敗します。

お教えていただきたいのは、共有ライブラリを作成する時に必ず指定しなければならない
コンパイルオプションかリンクオプションが、あるのでしょうか?

共有ライブラリ作成時に指定しているオプションは、以下の通りです。

  • コンパイルオプション
    インクルード・パス:(-l xxxxxx)
    最適化:なし(-O0)
    デバッグレベル:最大(-g3)
    全ての警告(-Wall)
    その他のフラグ:-c -fmessage-length=0 -fPIC

  • リンクオプション
    ライブラリの検索パス:(-L xxxxxx)
    共有(-shared)

確認した環境は、以下の通りです。

CentOS7(7.8.2003)
Eclipse 2020-03(4.15.0)
CDT 9.11(2020-03)
gcc-c++(4.8.5)
JDK(11)

以下、エラーメッセージです。

Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'CAESSecurity': /home/css/eclipse-workspace/CryptoWithA4kCommonLibrarySample/bin/libAESSecurityLibrary.so: undefined symbol: CAESSecurity
    at com.sun.jna.Function.<init>(Function.java:252)
    at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:600)
    at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:576)
    at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:562)
    at com.sun.jna.Library$Handler.invoke(Library.java:243)
    at com.sun.proxy.$Proxy0.CAESSecurity(Unknown Source)
    at CryptoSample.encryptToken(CryptoSample.java:25)
    at mainSample.main(mainSample.java:11)

以下、プログラムです。

CAESSecurity::CAESSecurity(bytes& key, bytes& IV, int keytype)
: m_key(key), m_IV(IV), m_keytype(keytype)
{
    /* Load up the software EVP_CIPHER definitions */
    OpenSSL_add_all_ciphers();
#ifndef OPENSSL_NO_ENGINE
    /* Load all compiled-in ENGINEs */
    ENGINE_load_builtin_engines();
    /* Register all available ENGINE implementations of ciphers. */
    ENGINE_register_all_ciphers();
#endif

}
      // 暗号化&復号化で使用する鍵
      private static final byte[] ENCRYPT_KEY = new byte[] { (byte)0x9C, (byte)0x5D, (byte)0x5A, (byte)0x42, (byte)0x8A, (byte)0x20, (byte)0x3D, (byte)0x7B, (byte)0x38, (byte)0x5D, (byte)0xAD, (byte)0x63, (byte)0x29, (byte)0xE6, (byte)0xD2, (byte)0x16 };
      // 初期ベクトル
      private static final byte[] INIT_VECTOR = new byte[] { (byte)0xBB, (byte)0xC0, (byte)0xCE, (byte)0xC6, (byte)0xAE, (byte)0xB8, (byte)0x47, (byte)0x9D, (byte)0xE2, (byte)0xA3, (byte)0x85, (byte)0x93, (byte)0x13, (byte)0xA7, (byte)0x88, (byte)0x65 };

    public interface A4kCommonLibrary extends Library {
        A4kCommonLibrary INSTANCE = (A4kCommonLibrary)Native.loadLibrary("AESSecurityLibrary", A4kCommonLibrary.class);

        void CAESSecurity(byte[] key, byte[] iv, int keyType);
        boolean Encode(byte[] in_bytes, byte[] out_bytes);
    }

      /**
       * 暗号化処理
       */
      public String encryptToken(String token) throws Exception {
          byte[] data = new byte[5000];
          A4kCommonLibrary Cipher = A4kCommonLibrary.INSTANCE;
          Cipher.CAESSecurity(ENCRYPT_KEY, INIT_VECTOR, 128);
          Cipher.Encode(token.getBytes(), data);

         // 暗号化
        return new String(data);
      }

共有ライブラリの作成手順を以下にまとめました。
※既存の処理を部分的に抜き出して共有ライブラリとして作成しています。

  1. Eclipseの新規プロジェクト(C/C++プロジェクト、C++管理ビルドテンプレート、空のプロジェクトを指定)を作成しました。
  2. 作成したプロジェクトにsrcディレクトリとincludeディレクトリを追加しました。
  3. 既存のプログラムをプロジェクトに追加(空ファイルを作成し、既存プログラムの内容をコピーする)しました。
  4. プロジェクトのプロパティで既存と同じ設定を指定しました(設定内容は、前出のコンパイルオプション、リンクオプションです)。
  5. ビルドしてライブラリを生成しました。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • coco_bauer

    2020/07/15 21:11

    libAESSecurityLibrary.so というファイルは、どういう手順で作られたのですか?
    未定義のシンボルで失敗するのは、ライブラリファイル(libAESSecurityLibrary.so)を作るのに失敗しているからだと思われますから、作成手順を順を追って確認していくのが良いのではないでしょうか。

    キャンセル

  • fuoh

    2020/07/15 21:19

    早速のご対応ありがとうございます。
    作成手順については、整理して記載いたします。

    キャンセル

  • YT0014

    2020/07/16 10:42

    この現象ではないでしょうか?
    https://oshiete.goo.ne.jp/qa/9527324.html

    キャンセル

  • fuoh

    2020/07/16 11:06

    ご対応ありがとうございます。
    参考にさせていただきます。

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Javaに関する質問
  • C++で作成した共有ライブラリ(so)をJava(JNA)で参照しようとしたが、「undefined symbol (未定義のシンボル)」で失敗します。