简体   繁体   English

如何使用具有相同回调签名的 JNA in.dll and.so

[英]How to use JNA in .dll and .so with the same callback signature

I'm working on a java project to run on both Windows and Linux, and I'm using a third party shared library available to both operating systems with the same methods' signature.我正在开发一个 java 项目以在 Windows 和 Linux 上运行,并且我正在使用第三方签名库。两个操作系统都可以使用相同的方法But, the dll's calling convention is stdcall while the shared object is cdecl.但是,dll 的调用约定是 stdcall,而共享的 object 是 cdecl。

I'd like to avoid duplicate the callback code, two interfaces and two classes, one interface for each calling convention.我想避免重复回调代码,两个接口和两个类,每个调用约定一个接口。 I would like to write a single code for the callback function.我想为回调 function 编写一个代码。 Is that possible?那可能吗?

The only change in the code below to access.so in linux is the interface.下面代码中对linux中access.so的唯一更改是接口。 The callback function code itself is the same.回调 function 代码本身也是一样的。 I'll appreciate any sugestion.我会很感激任何建议。

import com.sun.jna.Callback;
interface IExternLibCallback extends Callback {..}

This is the code that I wrote for the callback in dll:这是我为 dll 中的回调编写的代码:

//Interface to stdcall (Windows)
package test1;
import com.sun.jna.win32.StdCallLibrary;
interface IExternLibCallback extends StdCallLibrary.StdCallCallback  {

      void callback (JEventDataStructure context_data);
}

//Class that implements the interface
package test1;
class ExternLibCallback implements IExternLibCallback  {

     ... Other class codes go here ....

  @ Override
  public void callback (JEventDataStructure contextData) {

     ... Code of callback function
  }
}

Thanks,谢谢,

Fernando费尔南多

You can declare them both with StdCallLibrary/StdCallCallback, but the behavior might not be defined on all platforms.您可以使用 StdCallLibrary/StdCallCallback 声明它们,但可能并非在所有平台上都定义了行为。 The option is ignored on platforms that don't support an alternate calling convention (which is everything except win32 at the moment), but hasn't necessarily been tested on all platforms.该选项在不支持备用调用约定的平台上被忽略(目前是除 win32 之外的所有平台),但不一定在所有平台上都经过测试。

This is the preferred definition, which defines the stdcall library only for windows.这是首选定义,它仅为 windows 定义 stdcall 库。

interface MyLibrary extends Library {
   interface MyCallback extends Callback {
       public void invoke();
   }
   void callbackFunction(MyCallback cb);
   MyLibrary INSTANCE = (MyLibrary)Native.loadLibrary("mylib", Platform.isWindows() ? MyWin32Library.class : MyLibrary.class);
}
interface MyWin32Library extends MyLibrary, StdCallLibrary {
   interface MyStdCallCallback extends MyCallback, StdCallCallback {}
   void callbackFunction(MyStdCallCallback cb);
}

If you're just targeting linux and windows, then a single interface may suffice (I'd recommend testing this, though):如果您只是针对 linux 和 windows,那么单个接口可能就足够了(不过我建议您对此进行测试):

interface MyLibrary extends StdCallLibrary {
   interface MyCallback extends StdCallCallback {
       public void invoke();
   }
   void callbackFunction(MyCallback cb);
   MyLibrary INSTANCE = (MyLibrary)Native.loadLibrary("mylib", MyLibrary.class);
}

I would have another wrapper around the JNAWrapper.我会在 JNAWrapper 周围有另一个包装器。 So for example, if the JNA wrapper for the dll is called IExternLibWindows and the one for Linux is called IExternLibLinux , i would write another wrapper - IExternLib .例如,如果 dll 的 JNA 包装器称为IExternLibWindows ,而 Linux 的 JNA 包装器称为IExternLibLinux ,我会编写另一个包装器 - IExternLib then,然后,

 public interface IExternLibWindows extends StdCallLibrary{
  public IExternLibWindows Instance ;
 ...
   void stdcall_somefunc(...);
 ...
 }

 public interface IExternLibLinux extends StdCallLibrary{
  public IExternLibLinux Instance ;
 ...
   void cdecl_somefunc(...);
 ...
 }

 public class IExternLib(){

    public void somefunc(...){
        if(System.getProperty("os.name").startsWith("Windows"))
            IExternLibWindows.stdcall_somefunc(...);
        else if(System.getProperty("os.name").startsWith("Linux"))
            IExternLibLinux.cdecl_somefunc(...);

    }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM