JNA:在 Spotify API 中找不到 C 方法
我试图了解 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);
}
}
这是我尝试访问的方法的 C 声明,在 libspotify 的 api.h 中:
/**
* 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);
/** @} */
谢谢!
I was trying to learn how JNA works, so I decided to use the spotify API (libspotify 0.0.7). I managed to load my dll correctly, but then it looks like my code is not finding any of the method defined in the API.
Here is my test code:
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);
}
}
Here is the C declaration of the method I try to access, in the api.h of libspotify:
/**
* 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);
And here is my 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)
Is there a problem with my DLL, or am I doing something wrong?
By the way, I don't have access to the definition of the sp_artist structure in C, I just reconstructed it based on the methods offered by the API, could it be the problem?:
/**
* @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);
/** @} */
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我终于通过使用 Dependency Walker 打开 libspotify.dll 找到了解决方案:
编译器向方法名称添加了一些额外信息(下划线前缀和@4或@8后缀)。
我必须:
I finally found the solution by opening the libspotify.dll with Dependency Walker:
The compiler added some extra information to the method name (a underscore prefix and a @4 or @8 suffix).
I had to: