2023-01-20 428
我试图学习JNA的工作原理,因此我决定使用Spotify API(libspotify 0.0.7).我设法正确地加载了我的dll,但是看起来我的代码没有找到API中定义的任何方法.
这是我的代码:
我的主文件:
public class Test{
private static final int SPOTIFY_API_VERSION = 7;
private static final char[] APP_KEY = { /* MY APP KEY HERE */ };
static{
System.loadLibrary("libspotify");
}
public static void main(String[] args){
JLibspotify libs = JLibspotify.INSTANCE;
sp_session mySession = new sp_session();
sp_session_config cfg = new sp_session_config();
cfg.api_version = SPOTIFY_API_VERSION;
cfg.cache_location = "tmp";
cfg.settings_location = "tmp";
cfg.application_key = APP_KEY;
cfg.application_key_size = APP_KEY.length;
cfg.user_agent = "spshell";
cfg.callbacks = null;
libs.sp_session_create(cfg, mySession);
}
}
我的库接口:
public interface JLibspotify extends Library {
JLibspotify INSTANCE = (JLibspotify)Native.loadLibrary("libspotify", JLibspotify.class);
// Methods definitions
sp_error sp_session_create(sp_session_config config, sp_session sess);
}
我的sp_session对象(不透明C结构)
public class sp_session extends PointerType{
public sp_session(Pointer address) {
super(address);
}
public sp_session() {
super();
}
}
我的sp_session_config对象
public class sp_session_config extends Structure{
public int api_version; // The version of the Spotify API your application is compiled with.
public String cache_location;
public String settings_location;
public char[] application_key}; // Your application key.
public int application_key_size; // The size of the application key in bytes
public String user_agent;
public sp_session_callbacks callbacks; // Delivery callbacks for session events. NULL if not interested in any callbacks
public Pointer userdata; // User supplied data for your application
public boolean compress_playlists;
public boolean dont_save_metadata_for_playlists;
public boolean initially_unload_playlists;
}
我的sp_error枚举
public enum sp_error {
SP_ERROR_OK,
SP_ERROR_BAD_API_VERSION,
SP_ERROR_API_INITIALIZATION_FAILED,
SP_ERROR_TRACK_NOT_PLAYABLE,
SP_ERROR_RESOURCE_NOT_LOADED,
SP_ERROR_BAD_APPLICATION_KEY,
SP_ERROR_BAD_USERNAME_OR_PASSWORD,
SP_ERROR_USER_BANNED,
SP_ERROR_UNABLE_TO_CONTACT_SERVER,
SP_ERROR_CLIENT_TOO_OLD,
SP_ERROR_OTHER_PERMANENT,
SP_ERROR_BAD_USER_AGENT,
SP_ERROR_MISSING_CALLBACK,
SP_ERROR_INVALID_INDATA,
SP_ERROR_INDEX_OUT_OF_RANGE,
SP_ERROR_USER_NEEDS_PREMIUM,
SP_ERROR_OTHER_TRANSIENT,
SP_ERROR_IS_LOADING,
SP_ERROR_NO_STREAM_AVAILABLE,
SP_ERROR_PERMISSION_DENIED,
SP_ERROR_INBOX_IS_FULL,
SP_ERROR_NO_CACHE,
SP_ERROR_NO_SUCH_USER
}
我的异常堆栈跟踪
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'sp_session_create': 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_session_create(Unknown Source)
at com.nbarraille.jspotify.main.Test.main(Test.java:49)
我试图运行的方法的C ++声明
/**
* Initialize a session. The session returned will be initialized, but you will need
* to log in before you can perform any other operation
*
* Here is a snippet from \c spshell.c:
* @dontinclude spshell.c
* @skip config.api_version
* @until }
*
* @param[in] config The configuration to use for the session
* @param[out] sess If successful, a new session - otherwise NULL
*
* @return One of the following errors, from ::sp_error
* SP_ERROR_OK
* SP_ERROR_BAD_API_VERSION
* SP_ERROR_BAD_USER_AGENT
* SP_ERROR_BAD_APPLICATION_KEY
* SP_ERROR_API_INITIALIZATION_FAILED
*/
SP_LIBEXPORT(sp_error) sp_session_create(const sp_session_config *config, sp_session **sess);
i 最后通过用依赖性沃克打开libspotify.dll找到解决方案:
编译器为方法名称添加了一些额外的信息(一个下划线前缀和 @4或 @8后缀).
我必须:
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?
如果您无法访问它,JNA也没有.如果是不透明的类型,请寻找用于创建,修改和删除的函数.
另外,您是否在上述语句上遇到了错误,Java变量的五行定义”艺术家”?
@technomage ‘ -Found/5162171#comment9938104_5162171″>评论非常有帮助.这是详细信息:
对于所有平台,接口可以保持不变:
Foo extends Library {
void foo();
}
只需添加StdCallLibrary.FUNCTION_MAPPER函数映射:
Map<String, ?> options = Collections.singletonMap(
Library.OPTION_FUNCTION_MAPPER,
StdCallLibrary.FUNCTION_MAPPER
);
Foo proxy = Native.loadLibrary("foo", Foo.class, options);
在Windows 7 32位,Mac OS 10.13.2,Unpuntu Linux 16.04 64位上使用JNA 4.5.1.我还没有测试过其他平台,也没有自己编译本地图书馆,因此您的里程可能会有所不同.
这里有更多细节:
最初,我的界面看起来像这样:
Foo extends Library {
void foo();
}
我试图这样加载本地库:
Native.loadLibrary("foo", Foo.class);
在Mac和Linux上工作,但在Windows 7 32-bit上工作:错误查找函数’foo’:找不到指定的过程.
所以我更改了界面:
Foo extends StdCallLibrary {
void foo();
}
我尝试使用stdcall特定函数映射加载库:
Map<String, ?> options = Collections.singletonMap(
Library.OPTION_FUNCTION_MAPPER,
StdCallLibrary.FUNCTION_MAPPER
);
Foo proxy = Native.loadLibrary("foo", Foo.class, options);
现在它在Windows 7 32位上工作,但在Mac或Linux上不使用:未识别的通话约定:63 : – (
我以为每个平台需要不同的代码路径,甚至可以动态添加Library或StdCallLibrary接口(使用另一个Proxy),但后来我发现我们可以吃午餐并吃饭它也!见上文.
我不确定这种特殊行为是由JNA指定的,还是可能随着JNA的下一个发行版而改变的幸运事故.无论如何,这对我来说已经足够了.
以上所述是小编给大家介绍的JNA:找不到指定的程序,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/25940.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态