1

JNAがどのように機能するかを学ぼうとしていたので、spotify API(libspotify 0.0.7)を使用することにしました。dllを正しくロードできましたが、コードがAPIで定義されたメソッドを検出していないようです。

これが私のテストコードです:

public class Test { 
    static{
        System.loadLibrary("libspotify");
    }

    public interface LibSpotify extends Library {
        public static class sp_artist extends Structure{
            public String name;
            public boolean isLoaded;
            public int refCount;
        };

        LibSpotify INSTANCE = (LibSpotify)Native.loadLibrary("libspotify", LibSpotify.class);

        public String sp_artist_name(sp_artist artist);
    }

    public static void main(String[] args){
        LibSpotify ls = LibSpotify.INSTANCE;

        LibSpotify.sp_artist artist = new LibSpotify.sp_artist(){
            String name = "thename";
            boolean isLoaded = false;
            int refCount = 0;
        };

        ls.sp_artist_name(artist);
    }
}

libspotifyのapi.hで、アクセスしようとしているメソッドのC宣言を次に示します。

/**
 * Return name of artist
 *
 * @param[in]   artist     Artist object
 *
 * @return                 Name of artist.
 *                         Returned string is valid as long as the artist object stays allocated
 *                         and no longer than the next call to sp_session_process_events()
 */
SP_LIBEXPORT(const char *) sp_artist_name(sp_artist *artist);

そして、これが私のStackTraceです。

Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'sp_artist_name': The specified procedure could not be found.

    at com.sun.jna.Function.<init>(Function.java:129)
    at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:250)
    at com.sun.jna.Library$Handler.invoke(Library.java:191)
    at $Proxy0.sp_artist_name(Unknown Source)
    at com.nbarraille.jspotify.main.Test2.main(Test2.java:33)

DLLに問題がありますか、それとも何か問題がありますか?

ちなみに、Cのsp_artist構造体の定義にアクセスできません。APIが提供するメソッドに基づいて再構築しただけですが、問題になる可能性がありますか?:

/**
 * @defgroup artist Artist subsystem
 * @{
 */

/**
 * Return name of artist
 *
 * @param[in]   artist     Artist object
 *
 * @return                 Name of artist.
 *                         Returned string is valid as long as the artist object stays allocated
 *                         and no longer than the next call to sp_session_process_events()
 */
SP_LIBEXPORT(const char *) sp_artist_name(sp_artist *artist);

/**
 * Check if the artist object is populated with data
 *
 * @param[in]   artist     An artist object
 *
 * @return                 True if metadata is present, false if not
 *
 */
SP_LIBEXPORT(bool) sp_artist_is_loaded(sp_artist *artist);


/**
 * Increase the reference count of a artist
 *
 * @param[in]   artist       The artist object
 */
SP_LIBEXPORT(void) sp_artist_add_ref(sp_artist *artist);

/**
 * Decrease the reference count of a artist
 *
 * @param[in]   artist       The artist object
 */
SP_LIBEXPORT(void) sp_artist_release(sp_artist *artist);

/** @} */

ありがとう!

4

1 に答える 1

0

Dependency Walkerを使用してlibspotify.dllを開くことで、最終的に解決策を見つけました。コンパイラーは、メソッド名にいくつかの追加情報(アンダースコアプレフィックスと@4または@8サフィックス)を追加しました。

そうしなければならなかった:

  • 実名に従ってすべてのメソッドの名前を変更するFunctionMapperの実装を作成します(Dependency Walkerで使用可能)
  • オプションマップでこのマッパーのインスタンスを使用してライブラリをインスタンス化します。
于 2011-03-02T00:45:23.190 に答える