【问题标题】:How to call existing c++ dll from java [duplicate]如何从java调用现有的c++ dll [重复]
【发布时间】:2014-12-09 23:15:02
【问题描述】:

我有一个以前用于 c# 应用程序的 c++ dll。现在我们想为 java 使用相同的 dll。我知道我们可以为此使用 JNI 技术,但问题是我们必须使用相同的方法签名,我们不想更改方法签名。请给我建议。

【问题讨论】:

  • 您确定您的库使用标准 C++ 吗? C# 不能访问 C++ 类,除非它们用 C++/CLI 包装。
  • 我相信这个问题不是重复的。 9485896 询问如何创建 C++ DLL 以使用 Java,并且接受的答案与此问题有关。这个问题是关于允许从 Java 访问现有方法的最小包装器。

标签: c++ java-native-interface shared-libraries


【解决方案1】:

您不必更改方法签名,只需添加一个本机方法,然后调用本机 C++ 代码。这是一个简单的例子:

public class Someclass
{
   public native void thisCallsCMethod(Someparams);
}

现在创建 JNI 包装器:

javac Someclass.java
javah Someclass

这将创建一个 Someclass.h,然后创建 Someclass.cpp 并将 .h 包含在其中。 此时,您所要做的就是为 thiCallsCMethod 编写 C/C++ 代码

在 .h 中,您会看到必须实现的方法签名。大致如下:

#include "clibraryHeader.h"
using namespace clibraryNamespace;

JNIEXPORT void JNICALL thisCallsCMethod(JNIEnv *, someparameters)
{
   cout<<"Yeah C code is being called"<<endl;
   someCfunction();
}

显然您必须在 JNI 调用中处理参数,但您可以创建一些临时变量,然后将从 C 调用中获得的值复制回传入参数(如果需要返回)等。

也许:

#include "clibraryHeader.h"
using namespace clibraryNamespace;

JNIEXPORT void JNICALL thisCallsCMethod(JNIEnv *, someparameters)
{
   cout<<"Yeah C code is being called"<<endl;
   Cstruct temp;
   temp1.somevar = param1.getSomeVal()
   someCfunction(temp);
}

【讨论】:

  • 这个答案没有回答如何调用现有 DLL 的问题,它可以/不应该被修改。
【解决方案2】:

一种选择是使用 JNA 而不是 JNI。它消除了对样板本机代码的需要。一个例子看起来像这样......

import com.sun.jna.Library;
import com.sun.jna.Native;

public class Example {

  public interface NativeMath extends Library {

    public bool isPrime(int x);
  }

  public static void main(String[] args) {

    int x = 83;

    NativeMath nm = (NativeMath) Native.loadLibrary("nm", NativeMath.class);

    System.out.println(x + " is prime: " + nm.isPrime(x));
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    相关资源
    最近更新 更多