JNA:找不到指定的程序

2023-12-11

我试图了解 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 finally通过使用 Dependency Walker 打开 libspotify.dll 找到了解决方案: 编译器向方法名称添加了一些额外信息(下划线前缀和@4或@8后缀)。

我不得不:

  • 创建 FunctionMapper 的实现,根据真实名称重命名我的所有方法(可在 Dependency Walker 中找到)
  • 在选项映射中使用此映射器的实例实例化我的库。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JNA:找不到指定的程序 的相关文章

随机推荐

  • 如何使用 Java 将 BsonDocument 对象写入文件并再次读取它

    我想将 BsonDocument 输出到文件系统 而不是 mongodb 然后使用 java 再次读取它 但目前的BasicBSONencoder仅支持旧版本的BSONObject 如何将BsonDocument编码为二进制 或者有什么方法
  • 如何在整个子查询上使用 group_concat?

    无需进行不必要的比较 我想获得一系列行的 md5 哈希值 由于带宽限制 我希望它发生在服务器端 这有效 create table some table id int auto increment col1 varchar 1 col2 in
  • 如何删除数据框列的标题

    我想出了一个像这样的数据框 我想知道我们如何更改或删除 id 和 date 因为它们只是索引和列的名称 id col1 col2 clo3 date 2000 01 03 55 500000 NaN NaN 2000 01 04 52 81
  • 使用 ImageMagick 将 PDF 转换为 PNG 或 JPEG 非常非常慢

    我有一个使用 PHP 和 ImageMagick 的 PDF 到 PNG 转换脚本 但我遇到了转换速度问题 我知道它是有效的 因为对于非常小的 PDF 转换所需的时间并不是那么长 但是对于 250kb 文件 实际上仍然不是那么大 转换需要超
  • 如何控制winform mschart图例文本对齐c#?

    如何设置图表图例对象中的文本对齐方式 我尝试过使用 myChartName Legends mySeriesName Alignment stringAlignment Near 没有效果 我还尝试创建自定义图例项目 同样没有效果 文本始终
  • FirefoxDriver webdriver.load.strategy 不稳定 findelements 从错误页面获取元素

    我在一个应用程序中使用 FirefoxDriver 该应用程序可以快速浏览几个相似但不相同的页面 为了加快执行速度 我需要使用 FF 我将 webdriver load strategy 属性设置为 不稳定 这确实通过不完全加载页面来加快速
  • python groupby 行为?

    gt gt from itertools import groupby gt gt keyfunc lambda x x gt 500 gt gt obj dict groupby range 1000 keyfunc gt gt list
  • 哪一种是表单验证的正确方法? Colander 的模式验证还是 Deform 的表单验证?

    我刚刚开始使用Pyramid对于我的一个项目 我有一种情况 我需要验证表单字段输入 方法是获取该表单字段值并进行 Web 服务调用来断言该值的正确性 例如 有一个字段称为您银行的 CUSTOMER ID 我需要将其 单独 作为输入 并通过进
  • TKinter 中的阿拉伯语文本

    我正在创建一个带有文本的窗口 我想在文本中使用阿拉伯语 root Tk root title Alram root geometry 1500x600 msg Message root bg red text The main interf
  • 使用递归函数反转字符串

    我目前正在学习 C 我无法通过这个练习 我必须创建一个递归函数来反转string1 into string2 这是我的代码 我将非常感谢您的帮助 include
  • 以编程方式访问 Windows 8.1 中最常用的应用程序

    Windows 8 1 开始菜单提供了可按最常用排序的应用程序列表 Windows 按钮 gt 向下箭头 gt 应用程序 按最常用排序 有没有办法以编程方式获取这些应用程序的列表按这个顺序在 C 中 如果不是按照这个顺序 至少是 Windo
  • 如何使用 Tuple/Array/Vector 从 Python (ctypes) 调用 PARI/GP?

    我想打电话PARI GP来自Python 我需要使用ellisdivisible E P n Q 帕里的功能 请参阅此链接中第 441 页的第 3 15 35 号功能 所以我必须传递 2 个向量或数组 例如 E ellinit 0 1 1
  • Spring MVC 和登录重定向

    我有一个网络应用程序 当用户单击个人资料链接时 如果他没有登录 我想将他重定向到登录页面 然后当他登录时 我会将他发送回他所拥有的链接原来点击了 在这种情况下 他的个人资料 我已经完成了将他重定向到登录页面的部分 但我试图找出如何记住他的初
  • Android 导航组件 - 更改根片段?

    假设我有片段 a gt b gt c 但 a 是启动画面 所以我希望 b 成为堆栈中的第一个片段并永远抛出 a 所以当我是 b 时然后按 后退 系统按钮 我关闭应用程序 在SupportFragmentManager中 我使用了replac
  • 以气流用户身份运行气流进程和气流网络服务器

    Problem 我正在 GCP 上设置 Google Compute Engine 虚拟机airflow安装在其上 我现在正在尝试整合airflow with systemd按照以下说明http airflow readthedocs io
  • 如何在 Android 的聊天或消息应用程序中发送表情符号(图像、笑脸)?

    如何发送在编辑文本中一起编写的文本和表情符号 图像 不是默认表情符号 资源文件夹中的图像 以发送该编辑文本中出现的消息和聊天 p s 我正在邮件或消息正文中发送这些图像 我正在尝试以下代码 public class MainActivity
  • 如何在Javascript中实时输出到控制台?

    在 Javascript 中 当您编写如下代码时 计算机似乎会首先完成整个循环 100 000 次 可能需要一两秒 然后一次转储控制台中的所有 100 000 行射击 我怎样才能使计算机每次通过循环一次更新控制台一行 为了澄清 我实际上希望
  • 如何在 Ruby 中进行高级字符串比较?

    我正在尝试比较两段字符串 其输出必须是相似度的百分比 我尝试过使用diff方法和一些Natural Language Processing tools 在红宝石中是否有更好的方法来做到这一点 您可能想为此尝试 Levenshtein 字符串
  • R 使用 lapply 保存绘图

    我有一个名为的模型对象列表allAR1 对于每个模型对象 我需要使用tsdiag函数生成诊断图 然后将该图保存到文件夹中 我正在尝试使用 jpeg lapply 和 dev off 的组合来应用tsdiag每个模型 然后将生成的图保存为图像
  • JNA:找不到指定的程序

    我试图了解 JNA 的工作原理 因此我决定使用 spotify API libspotify 0 0 7 我设法正确加载我的 dll 但看起来我的代码没有找到 API 中定义的任何方法 这是我的代码 我的主要文件 public class