2016-04-25 20 views
0

我当前的项目我需要从我的Java应用程序中使用一些C++代码。在我看来,常见的解决方案是从C++部分创建一个DLL并通过JNA访问它。因为我是一个初学者,当涉及到C++时,我想我从一个最基本的开始,继续从那里开始工作。不过,我甚至无法将这些最小的示例运行。下面是我所做的:JNA和C++ - 导致UnsatisfiedLinkError的简约示例

我用文档Visual Studio创建我的DLL(这里找到:https://msdn.microsoft.com/de-de/library/ms235636.aspx

你在那里做什么是你定义一个头

// 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); 
}; 
} 

和一个.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; 
} 
} 

然后将其构建到DLL中。到目前为止,这工作没有错误。 我然后就写了一个小的Java PROGRAMM通过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); 

    } 
} 

运行这将导致这个错误: 异常线程“main” java.lang.UnsatisfiedLinkError中:错误查找函数'添加':无法找到指定的过程。

我琢磨了一下,但无法解决问题。在这一点上,我几乎失去了,因为我没有看到自己能够构建一个更简单的例子 - 所以任何帮助或指针将非常感激。

+0

C++和C具有不同的接口(ABI),事实上,您正在使用CLibrary类型加载C++库,这对我来说已经看起来很可疑。另请参阅:[Java Native Access不执行C++,对不对?](http://stackoverflow.com/questions/2241685/java-native-access-doesnt-do-c-right)。您可能会更好地使用JNI,尽管这需要更多的工作。 –

回答

0

C++“mangles”根据编译器的意愿导出名称。例如,“void main(argc,argv)”可能会以“_Vmain_IPP @ xyzzy”的形式出现。

在您的DLL上运行depends.exe以查看导出的名称的样子。代码中的extern "C"将阻止C++修改导出的函数名称。

JNA处理静态函数就好了; JNAerator自动适应一些额外的损坏,但如果你想将C++类映射到Java类,那么最好用SWIG之类的东西。

+0

我试图使用extern“C”但它没有帮助。 depends.exe显示正确的函数名称,但有一个?在他们面前。到目前为止,我无法弄清楚为什么这是 – dhyr

+0

在你的问题中显示更新的源代码和depends.exe输出。 – technomage