简体   繁体   English

JNA和C ++-导致UnsatisfiedLinkError的简约示例

[英]JNA and C++ - Minimalistic Example resulting in UnsatisfiedLinkError

for my current project I need to use some c++ code from within my java application. 对于我当前的项目,我需要在Java应用程序中使用一些c ++代码。 It seems to me that the common solution is to create a DLL out of the c++ part and access it via JNA. 在我看来,常见的解决方案是从c ++部分创建一个DLL并通过JNA访问它。 As I'm a total beginner when it comes to c++ I figure I start with a minimal basis and continue work from there. 因为我是C ++的初学者,所以我认为我会以一个最小的基础开始,然后从那里继续工作。 However I can't even bring these minimal example to run. 但是,我什至不能带这些最小的例子来运行。 Here's what I did: 这是我所做的:

I used documentation for Visual Studio to create my DLL (found here: https://msdn.microsoft.com/de-de/library/ms235636.aspx ) 我使用了Visual Studio文档来创建我的DLL(位于此处: https : //msdn.microsoft.com/de-de/library/ms235636.aspx

What you do there is that you define a header 您要做的就是定义标题

// MathFuncsDll.h

#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport) 
#else
#define MATHFUNCSDLL_API __declspec(dllimport) 
#endif
namespace MathFuncs
{
 // This class is exported from the MathFuncsDll.dll
 class MyMathFuncs
 {
 public: 
    // Returns a + b
    static MATHFUNCSDLL_API double Add(double a, double b); 
 };
}

and a .cpp file 和一个.cpp文件

// MathFuncsDll.cpp : Defines the exported functions for the DLL application.

#include "stdafx.h"
#include "MathFuncsDll.h"
#include <stdexcept>

using namespace std;

namespace MathFuncs
{
 double MyMathFuncs::Add(double a, double b)
 {
    return a + b;
 }
}

And then build it into a DLL. 然后将其构建到DLL中。 So far this worked without error. 到目前为止,这没有错误。 I then proceeded to write a small Java Programm to access this DLL via JNA, again sticking to the JNA Documentation: 然后,我继续编写一个小型Java程序,以通过JNA访问此DLL,再次坚持使用JNA文档:

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

/** Simple example of JNA interface mapping and usage. */
public class HelloWorld {

  // 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() ? "zChaffDLL" : "c"), CLibrary.class);

      double Add(double a, double b);
  }

  public static void main(String[] args) {
      CLibrary.INSTANCE.Add(5d, 3d);

  }
}

Running this results in this error: Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'Add': the specified procedure could not be found. 运行此命令将导致以下错误:线程“主”中的异常java.lang.UnsatisfiedLinkError:查找函数“添加”时出错:找不到指定的过程。

I tinkered around a bit but couldn't solve the problem. 我稍作修改,但无法解决问题。 At this point I'm pretty much lost since I don't see myself able to construct an even easier example - so any help or pointers would be really appreciated. 在这一点上,我几乎迷失了,因为我看不到自己能够构建一个更简单的示例-因此,非常感谢任何帮助或指针。

C++ "mangles" exported names according to the compiler's whims. C ++根据编译器的异想天开“捣乱”导出名称。 For example, "void main(argc, argv)" might come out as "_Vmain_IPP@xyzzy". 例如,“ void main(argc,argv)”可能会以“ _Vmain_IPP @ xyzzy”的形式出现。

Run depends.exe on your DLL to see what the exported names look like. 在您的DLL上运行depends.exe ,以查看导出的名称。 extern "C" in your code will prevent C++ from mangling exported function names. 代码中的extern "C"将阻止C ++破坏导出的函数名。

JNA handles static functions just fine; JNA可以很好地处理静态函数; JNAerator accommodates some extra mangling automatically, but if you want to map C++ classes onto Java classes, you're better off with something like SWIG. JNAerator会自动提供一些额外的功能,但是如果您想将C ++类映射到Java类,最好使用SWIG之类的方法。

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

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