天天看點

Java調用已經編譯好的C++動态庫

借花獻佛, 順便給自己記個備忘

因工作需要, 可能要在Java程式中調用C++寫的動态庫, 是以上網查了些資料, 按照網上的例子(http://www.cnblogs.com/cy163/archive/2009/12/15/1624807.html)寫了個程式, 程式功能是去除字元串中的空格

原文環境: Win2000Server, JDK1.3, VC6.0

我的環境: Win10, JDK1.8, VS2010

Java主程式JavaCallCDLL2.java:

public class JavaCallCDLL2

{

public native String cTrim(String str);

static

{

System.loadLibrary("myDll"); //這一句是原文沒有的, 我這裡不加這一句就會報"Can't find dependent libraries"的錯

System.loadLibrary("javaCallcdll2");

}

public static void main(String args[])

{

JavaCallCDLL2 test = new JavaCallCDLL2();

String str1 = "I love you!";

String str2 = test.cTrim(str1);

System.out.println("調用c dll前");

System.out.println("str1 = " + str1);

System.out.println("調用c dll後");

System.out.println("str2 = " + str2);

}

}

編譯好的動态庫myDll.dll:

頭檔案:

#pragma once;

//該宏完成在dll項目内部使用__declspec(dllexport)導出 

//在dll項目外部使用時,用__declspec(dllimport)導入 

//宏DLL_IMPLEMENT在simpledll.cpp中定義 

#ifdef DLL_IMPLEMENT 

#define DLL_API __declspec(dllexport) 

#else 

#define DLL_API __declspec(dllimport) 

#endif 

DLL_API void Trim(char *lpString);

實作檔案:

#include "myDll.h"

void Trim(char *lpString)

{

int iCount = 0;

char *lpChar = lpString;

while(*lpChar)

{

if(*lpChar != ' ')

{

lpString[iCount] = *lpChar;

iCount++;   

}

lpChar++;

}

lpString[iCount++] = 0;

}

由于動态庫是已經編譯好的, 不能修改源代碼, 是以需要建立一個中介動态庫來調用它

是以, 先通過"javac JavaCallCDLL2.java"和"javah JavaCallCDLL2"兩個控制台指令得到頭檔案JavaCallCDLL2.h

然後編寫中介動态庫的實作檔案javaCallcdll2.cpp:

#include "JavaCallCDLL2.h"

#include "myDll.h"

#include <string.h>

JNIEXPORT jstring JNICALL Java_JavaCallCDLL2_cTrim(JNIEnv *env, jobject obj, jstring str)

{

char strTemp[1024] = {};

strcpy(strTemp, env->GetStringUTFChars(str, NULL));

//錯誤出現時   

if(strTemp==NULL)

{

return NULL;

}

Trim(strTemp);

return   env->NewStringUTF(strTemp);

env->ReleaseStringUTFChars(str, strTemp);

}

附加包含目錄裡添加兩項: JavaJDK安裝目錄下的include, 以及include下的win32

把myDll.h和myDll.dll以及myDll.lib拷到javaCallcdll2工程目錄下

編譯得到javaCallcdll2.dll

将javaCallcdll2.dll和myDll.dll放到Java工程目錄下, 主程式就能運作了

Java調用已經編譯好的C++動态庫

好吧, 我個人要記住的就是: 動态庫, 以及動态庫依賴的動态庫都要通過System.loadLibrary()函數來加載, 否則就會報錯