让 JNA 与 Java 一起工作 => C#?

发布于 2024-11-07 04:44:57 字数 1143 浏览 5 评论 0 原文

我已经在 C# 库中编写了很多代码,现在需要从 Java 调用它们。

我看到有人建议使用 JNA,但我什至无法摆脱起始块;那里的文档非常粗略。

首先,它似乎只是向您展示如何连接到 Native C 库,这对我来说没有好处;我想连接到我自己的图书馆。那里的代码示例显示:

// This is the standard, stable way of mapping, which supports extensive
// customization and mapping of Java to native types.
public interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary)
        Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
                           CLibrary.class);

    void printf(String format, Object... args);
}

我想连接到我的库 (MyLibrary.dll),并调用 MyNamespace.MyClass 上的静态方法,其 C# 签名是:

public static string HelloWorld(string p)

那么我要给 提供哪些参数Native.loadLibrary()?

这只是“你好世界”。如果我想返回一个对象怎么办?假设 MyClass 也有一个静态方法,

public static MyClass GetInstance()

我如何使用 JNA 调用它?我想我必须在 Java 中定义一个与 C# MyClass 接口相匹配的接口...但是它必须是详尽的,即对于 MyClass 的每个公共成员我必须在 Java 的 IMyClass 接口中声明一个方法吗?或者我可以省略我不关心的接口吗?

任何示例代码将不胜感激!

I've written a lot of code in a C# library, which I now need to call from Java.

I saw it recommended on SO to use JNA, but I'm having trouble even getting out of the starting blocks; the documentation there is very sketchy.

Firstly, it only appears to show you how to connect to the Native C library, which is no good to me; I want to connect to my own library. The code sample there shows:

// This is the standard, stable way of mapping, which supports extensive
// customization and mapping of Java to native types.
public interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary)
        Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
                           CLibrary.class);

    void printf(String format, Object... args);
}

I want to connect to my library (MyLibrary.dll), and call a static method on MyNamespace.MyClass whose C# signature is:

public static string HelloWorld(string p)

So what parameters to I give to Native.loadLibrary()?

That's just for "Hello World". What if I want to return an object? Let's say MyClass also has a static method

public static MyClass GetInstance()

How would I call that using JNA? I guess I would have to define an interface in Java that matches the C# MyClass interface... but would it have to be exhaustive, i.e. for every public member of MyClass I would have to declare a method in an IMyClass interface in Java? Or can I just leave out the interfaces I don't care about?

Any sample code would be gratefully welcomed!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

攀登最高峰 2024-11-14 04:44:57

您将无法从 Java 直接调用 C# 代码。 JNA 将只能访问本机库(C 或 C++)。但是,您可以在库中启用 COM Interop,并将两者与本机包装器链接在一起。即它看起来像:

Java --(JNA)--> C/C++ --(COM 互操作)--> C#

有几种替代方案:

  • 使 C# 成为独立的命令行应用程序,并让 Java 代码使用 stdin/stdout (ProcessBuilder 可以在这里为您提供帮助)。
  • 将 C# 作为独立应用程序运行,并使用某种形式的平台中立消息传递协议在两者之间进行通信,例如 HTTP、AMQP。

You won't be able to call directly into your C# code from Java. JNA will only be able to access a native library (C or C++). However you could enable COM Interop in your library and link the 2 together with a native wrapper. I.e. it would look some thing like:

Java --(JNA)--> C/C++ --(COM Interop)--> C#

There are a couple of alternatives:

  • Make the C# a stand alone command line app and have the Java code send/receive data from it using stdin/stdout (ProcessBuilder can help you here).
  • Run the C# as a stand alone app with some form of platform neutral messaging protocol to communicate between the 2 of them, e.g. HTTP, AMQP.
乄_柒ぐ汐 2024-11-14 04:44:57

这个 Nugget 非常易于使用并且工作完美。 )

您需要 Visual Studio 2012(Express 可以工作 美好的)。
安装后,只需在要导出的任何静态函数之前添加 [RGiesecke.DllExport.DllExport] 即可。就是这样!

示例:

C#

[RGiesecke.DllExport.DllExport]
public static int YourFunction(string data)
{
     /*Your code here*/
     return 1;
}

Java

在顶部添加导入:

   import com.sun.jna.Native;

在类中添加接口。它是您的 C# 函数名称,前面带有字母“I”:

  public interface IYourFunction extends com.sun.jna.Library
    {
       public int YourFunction(String tStr);
    };

在您的类中需要的地方调用您的 DLL:

IYourFunction iYourFunction = (IYourFunction )Native.loadLibrary("full or relative path to DLL withouth the .dll extention", IYourFunction.class);//call JNA
        System.out.println("Returned: " + IYourFunction.YourFunction("some parameter"));

This Nugget is super easy to use and works perfectly. https://www.nuget.org/packages/UnmanagedExports

You need Visual Studio 2012 (Express works fine).
Once installed, just add [RGiesecke.DllExport.DllExport] before any static function you want to export. That's it!

Example:

C#

[RGiesecke.DllExport.DllExport]
public static int YourFunction(string data)
{
     /*Your code here*/
     return 1;
}

Java

Add the import at the top:

   import com.sun.jna.Native;

Add the interface in your class. Its your C# function name preceded by the letter "I":

  public interface IYourFunction extends com.sun.jna.Library
    {
       public int YourFunction(String tStr);
    };

Call your DLL where you need it in your class:

IYourFunction iYourFunction = (IYourFunction )Native.loadLibrary("full or relative path to DLL withouth the .dll extention", IYourFunction.class);//call JNA
        System.out.println("Returned: " + IYourFunction.YourFunction("some parameter"));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文