使用 Java 包装C++

2022-09-04 08:24:17

我有一个用C++编写的项目,我希望编写一个Java GUI作为它的接口。Java的选择是固定的,所以我需要学习如何从Java调用C++代码。重写C++代码不是一种选择。我想输入:

  1. 我可以使用哪些工具来实现此包装。
  2. 我必须修改多少C++代码(如果有的话)。
  3. 您有的任何其他见解/后续问题。

谢谢。


答案 1

我最近在做一个项目,在这个项目中,我们必须做同样的事情。我们有一个用C++编写的数据模型,需要将Java GUI放在顶部。我们最终所做的是确定我们需要从GUI访问C++类,并使用SWIG生成简单的旧java类,这些类包装了C++对象。

http://www.swig.org/

SWIG 生成的 Java 类与它们包装的C++类具有相同的接口,这意味着与来自 Java 的C++对象进行通信仅涉及使用 Java 对象。

下面是一个示例:

给定两个C++类:

class SomeClass {
public:
  void foo(SomeOtherClass bar);
  SomeOtherClass baz();
}

class SomeOtherClass {
public:
  void do();
}

SWIG 将生成两个 Java 类:

public class SomeClass {
  public void foo(SomeOtherClass bar);
  public SomeOtherClass baz();
}

public class SomeOtherClass {
  public void do();
}

从Java调用C++对象就像编写常规Java一样:

SomeClass sc = new SomeClass();
SomeOtherClass soc = sc.baz();
sc.foo(soc);

第 1 行:SomeClass 的 Java 包装器以及 SomeClass 类型的C++对象被实例化。

第 2 行:对 SomeClass 的 sc 实例的调用将转发到 SomeClass 的C++实例。C++实例的返回值将传递到 Java 包装器,并由 Java 包装器返回。

第 3 行:SWIG 处理从 Java 包装器类型(或 java 基元类型)到基础C++类型的转换。

SWIG将负责在方法调用期间与Java/C++类型之间的转换,并且所有JNI详细信息都隐藏在视图之外:)

为C++类生成 Java 包装器所需的 SWIG 接口代码可以很简单:

interface.i: { #include “ClassDefinition.h” } %include “ClassDefinition.h”

SWIG非常强大。您需要做的任何事情都可以使用基本功能,类型映射,java代码类型映射或控制器来完成。

SWIG 还允许您的C++代码调用 Java 对象,而无需对现有的C++代码进行任何修改。这是一个称为“跨语言多态性”的功能。跨语言多态性实质上允许您创建C++类的子类的 Java 类。然后,您可以将这些 Java 类的实例作为参数传递给C++方法调用。从C++对传递的实例的任何调用都将转发回 Java 对象。我不会在这里详细介绍,但是一旦你克服了这个想法最初的震惊,它就不是很复杂了。


答案 2

断续器

  • 如果您的代码是 c++
  • JNI 是 Java 运行时的一部分
  • 声明本机函数并使用javah生成c / c ++标头
  • 编写 c/c++ 代码以将代码粘合到 java 方法

金航

  • 如果您的代码有一个 c api
  • 不适用于 c++ 类
  • JNA不是java运行时的一部分,jna.jar是300kb
  • 使用您使用的 c 方法声明 Java 接口
  • 编写java代码以将您的dll粘合到java
  • 需要创建 dll 函数使用的 c 结构的 java 副本

它们都是独立于平台的。我自己更喜欢jna,因为它很容易搞砸jni代码。周围也有几种依赖于平台的解决方案 - 但我不太了解它们。

  • JACOB: java COM bridge (windows)
  • ...

推荐