gpt4 book ai didi

java - C++ 非静态回调和 JNA

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:13:11 32 4
gpt4 key购买 nike

我正在尝试将 Java 中的 C++ API 与 JNA 结合使用。此 API 使用回调来处理 session 事件。

我找到的关于如何使用 JNA 注册回调的唯一资源是 this ,它处理 C 回调,我真的不知道如何将它扩展到 C++ 非静态回调。

编辑:我刚找到 this resource ,我认为“回顾回调”一章可能会有帮助。

回调的所有函数指针都存储在以下 sp_session_callbacks 结构中:

/**
* Session callbacks
*
* Registered when you create a session.
* If some callbacks should not be of interest, set them to NULL.
*/
typedef struct sp_session_callbacks {
void (__stdcall *logged_in)(sp_session *session, sp_error error);
void (__stdcall *logged_out)(sp_session *session);
void (__stdcall *connection_error)(sp_session *session, sp_error error);
void (__stdcall *message_to_user)(sp_session *session, const char *message);
// Other callbacks function pointers
} sp_session_callbacks;

我创建的用于描述此结构的 Java 类如下:

public class sp_session_callbacks extends Structure{
public Function logged_in;
public Function logged_out;
public Function connection_error;
public Function message_to_user;
}

在您看来,在这种情况下,用 com.sun.jna.Function 对象表示函数指针是否有意义?

每个 session 都由一个 sp_session 对象表示,它是一个 C++ 不透明结构。不过,在初始化 sp_session_callbacks 对象时,我确实有一个句柄。

这是我的主类的代码片段:

JLibspotify lib = (JLibspotify)Native.loadLibrary("libspotify", JLibspotify.class);

sp_session_config cfg = new sp_session_config();
/* Some cfg config here */
sp_session_callbacks sessCallbacks = new sp_session_callbacks(); // Handle on my sp_session_callbacks object
cfg.callbacks = sessCallbacks;

PointerByReference sessionPbr = new PointerByReference();
int errorId = lib.sessionCreate(cfg, sessionPbr);

sp_session session = new sp_session(sessionPbr.getValue()); // handle on my sp_session object

我应该如何注册这些回调函数,以便在它们被触发时在 Java 端实际执行某些操作?

谢谢!

编辑

使用回调而不是函数的新代码:

public class sp_session_callbacks extends Structure{
public LoggedIn logged_in;
/* Other callbacks... */
}



public interface LoggedIn extends StdCallCallback {
public void logged_in(sp_session session, int error);
}

主类:

JLibspotify lib = (JLibspotify)Native.loadLibrary("libspotify", JLibspotify.class);

sp_session_config cfg = new sp_session_config();
/* Some cfg config here */
sp_session_callbacks sessCallbacks = new sp_session_callbacks(); // Handle on my sp_session_callbacks object
LoggedIn loggedInCallback = new LoggedIn(){
public void logged_in(sp_session session, int error){
System.out.println("It works");
}
};
sessCallbacks.logged_in = loggedInCallback;
/* Setting all the other callbacks to null */

cfg.callbacks = sessCallbacks;

PointerByReference sessionPbr = new PointerByReference();
int errorId = lib.sessionCreate(cfg, sessionPbr);

sp_session session = new sp_session(sessionPbr.getValue()); // handle on my sp_session object

当 cfg.logged_in 未设置为 null 而是设置为 LoggedIn 的实例时,sessionCreate() 调用将引发 JRE fatal error (EXCEPTION_ACCES_VIOLATION 0x0000005)。奇怪的是 logged_in 和 connection-error 这两个回调具有相同的签名,并且当设置 cfg.connection_error 时,它不会抛出任何东西。

最佳答案

从 javadoc Function 表示一个本地方法,如果你想调用一个 java 方法你必须创建一个 Callback对于每个函数指针。

如果您只使用 java 回调而不使用 native 函数,则可以将函数替换为回调。 (根据使用的调用约定,您可能希望改用 StdCallLibrary.StdCallCallback)

public class sp_session_callbacks extends Structure{
public StdCallCallback logged_in;
public StdCallCallback logged_out;
public StdCallCallback connection_error;
public StdCallCallback message_to_user;
}

sp_session_callbacks calls = new sp_session_callbacks();
calls.logged_out = new StdCallCallback(){

public void someName(sp_session sp){...}
}

关于java - C++ 非静态回调和 JNA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5193929/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com