2016-04-25 18 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