當前位置:首頁 » 編程軟體 » jni怎麼編譯c

jni怎麼編譯c

發布時間: 2022-05-26 08:48:10

① android jni程序(c++)如何編譯適用於arm-v8指令集的32位程序

可以看到Android上層的Application和ApplicationFramework都是使用java編寫,

底層包括系統和使用眾多的LIiraries都是C/C++編寫的。

所以上層Java要調用底層的C/C++函數庫必須通過Java的JNI來實現。

下面將學習Android是如何通過Jni來實現Java對C/C++函數的調用。以HelloWorld程序為例:

第一步:

使用Java編寫HelloWorld 的Android應用程序:

package com.lucyfyr;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class HelloWorld extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.v("fresne", printJNI("I am HelloWorld Activity"));
}
static
{
//載入庫文件
System.loadLibrary("HelloWorldJni");
}
//聲明原生函數 參數為String類型 返回類型為String
private native String printJNI(String inputStr);
}

這一步我們可以使用eclipse來生成一個App;

因為eclipse會自動為我們編譯此Java文件,後面要是用到。

第二步:

生成共享庫的頭文件:

進入到eclipse生成的Android Project中 :/HelloWorld/bin/classes/com/lucyfyr/
下:

可以看到裡面後很多後綴為.class的文件,就是eclipse為我們自動編譯好了的java文件,其中就有:

HelloWorld.class文件。

退回到classes一級目錄:/HelloWorld/bin/classes/

執行如下命令:

javah com.lucyfyr.HelloWorld

生成文件:com_lucyfyr_HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lucyfyr_HelloWorld */
#ifndef _Included_com_lucyfyr_HelloWorld
#define _Included_com_lucyfyr_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_lucyfyr_HelloWorld
* Method: printJNI
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif

可以看到自動生成對應的函數:Java_com_lucyfyr_HelloWorld_printJNI

Java_ + 包名(com.lucyfyr) + 類名(HelloWorld) + 介面名(printJNI):必須要按此JNI規范來操作;

java虛擬機就可以在com.simon.HelloWorld類調用printJNI介面的時候自動找到這個C實現的Native函數調用。

當然函數名太長,可以在.c文件中通過函數名映射表來實現簡化。

第三步:

實現JNI原生函數源文件:

新建com_lucyfyr_HelloWorld.c文件:

#include <jni.h>
#define LOG_TAG "HelloWorld"
#include <utils/Log.h>
/* Native interface, it will be call in java code */
JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI(JNIEnv *env, jobject obj,jstring inputStr)
{
LOGI("fresne Hello World From libhelloworld.so!");
// 從 instring 字元串取得指向字元串 UTF 編碼的指針
const char *str =
(const char *)(*env)->GetStringUTFChars( env,inputStr, JNI_FALSE );
LOGI("fresne--->%s",(const char *)str);
// 通知虛擬機本地代碼不再需要通過 str 訪問 Java 字元串。
(*env)->ReleaseStringUTFChars(env, inputStr, (const char *)str );
return (*env)->NewStringUTF(env, "Hello World! I am Native interface");
}
/* This function will be call when the library first be load.
* You can do some init in the libray. return which version jni it support.
*/
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
void *venv;
LOGI("fresne----->JNI_OnLoad!");
if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {
LOGE("fresne--->ERROR: GetEnv failed");
return -1;
}
return JNI_VERSION_1_4;
}

OnLoadJava_com_lucyfyr_HelloWorld_printJNI

函數裡面做一些log輸出 注意JNI中的log輸出的不同。

JNI_OnLoad函數JNI規范定義的,當共享庫第一次被載入的時候會被回調,

這個函數裡面可以進行一些初始化工作,比如注冊函數映射表,緩存一些變數等,

最後返回當前環境所支持的JNI環境。本例只是簡單的返回當前JNI環境。

http://www.cnblogs.com/bastard/archive/2012/05/19/2508913.html

② 用jni在代碼中怎樣實現java層調c的源碼

步驟一:
在java中定義一個c方法的介面 ,相當於在java代碼中定義了一個介面 介面的實現方法是c語言實現的。

public native String hello();

步驟二:
實現C代碼
方法名 嚴格按照jni的規范
#include <stdio.h>
#include <jni.h>
jstring Java_com_yys_helloworldformc_MainActivity_hello(JNIEnv* env,jobject obj){
// 2 步 實現C代碼
// 返回一個java String 類型的字元串
//jstring (*NewStringUTF)(JNIEnv*, const char*);
//(*env) 相當於 JNINativeInterface* JNIEnv
//*(*env) 相當於 JNINativeInterface
///return (**env).NewStringUTF(env,"helloworldfromc");
return (*env)->NewStringUTF(env,"helloworldfromc");
}

步驟三:
創建android.mk 告訴編譯器 如何把c代碼打包成函數庫

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
# 對應打包成函數庫的名字
LOCAL_MODULE := hello
# 對應c代碼的文件
LOCAL_SRC_FILES := Hello.c

include $(BUILD_SHARED_LIBRARY)

步驟四:
把c代碼 打包成函數庫 用到了安裝的環境 到相應目錄下使用ndk-build打包
5
步驟五:
在java代碼中 引入庫函數

static{
System.loadLibrary("hello");// 注意事項 去掉前面的lib 後面的.so

}

③ 如何用java調用c語言編譯器實現在線編譯c語

要在java中調用c語言的庫,需要使用Java提供了JNI。
舉例說明
在c語言中定義一個 void sayHello()函數(列印Hello World);然後在Java中調用這個函數顯示Hello Word.
現在分別從Java和C語言兩部分說明:
1. Java 部分
首先定義一個HelloNative,在其中申明sayHello函數,函數要申明為Native 類型的.如下:
public class HelloNative {
public native void sayHello();
}

編譯這個類,生成class文件:
javac HelloWorld.java

利用javah生成需要的h文件
javah HelloNative

生成的 h文件大概如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloNative
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloNative_sayHello
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

可以看一下上面自動生成的程序,程序include了jni.h,這個頭文件在 $JAVA_HOME下的include文件夾下. 還可以發現生成的函數名是在之前的函數名前面加上了Java_HelloNative。
2. C語言部分
根據上面生成的h文件編寫相應的代碼實現,建立一個 HelloNative.cpp用來實現顯示Hello World的函數.如下:

#include <stdio.h>
#include "HelloNative.h"

JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv *, jobject)
{
printf("Hello World!\n");
}

代碼編寫完成之後,我們再用gcc編譯成庫文件,命令如下;
gcc -fPIC -I/usr/lib/jvm/java-7-openjdk-i386/include -I/usr/lib/jvm/java-7-openjdk-i386/include/linux -shared -o libHelloNative.so HelloNative.cpp

這樣就會在當前目錄下生成一個libHelloNative.so的庫文件.這時需要的庫已經生成,在C語言下的工作已經完成了.
接下來需要在Java中編寫一個程序測試一下.在程序前,需要將我們的庫載入進去.載入的方法是調用Java的 System.loadLibrary("HelloNative");

public class TestNative
{
static {
try {
System.loadLibrary("HelloNative");
}
catch(UnsatisfiedLinkError e) {
System.out.println( "Cannot load hello library:\n " + e.toString() );
}
}
public static void main(String[] args) {
HelloNative test = new HelloNative();
test.sayHello();
}
}

但是再編譯後,運行的時候,問題又出現了.
Cannot load hello library:
java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: HelloNative.sayHello()V
at HelloNative.sayHello(Native Method)
at TestNative.main(TestNative.java:13)

載入庫失敗,但是庫明明就是放在當前文件夾下的,怎麼會載入失敗呢?
用System.getProperty("java.library.path")查看,發現java.library.path中並不u存在當前的目錄.主要有以下的幾個解決辦法:
1) 將生成的庫復制到java.library.path有的路徑中去,當然這樣不是很好
2) 設置環境變數export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ,將當前的目錄加入到LD_LIBRARY_PATH中
3) 設置java 的選項,將當前的目錄加入到其中 .java -Djava.library.path=. $LD_LIBRARY_PATH
這樣之後程序就能夠成功的運行了.可以看見顯示的"Hello World!"了

④ 怎麼用jni

·編寫帶有native聲明的方法的java類·使用javac命令編譯所編寫的java類·使用javah ?jni java類名生成擴展名為h的頭文件·使用C/C++實現本地方法·將C/C++編寫的文件生成動態連接庫·ok 1) 編寫java程序:這里以HelloWorld為例。 代碼1:class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("hello"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } } 聲明native方法:如果你想將一個方法做為一個本地方法的話,那麼你就必須聲明改方法為native的,並且不能實現。其中方法的參數和返回值在後面講述。 Load動態庫:System.loadLibrary("hello");載入動態庫(我們可以這樣理解:我們的方法 displayHelloWorld()沒有實現,但是我們在下面就直接使用了,所以必須在使用之前對它進行初始化)這里一般是以static塊進行載入的。同時需要注意的是System.loadLibrary();的參數「hello」是動態庫的名字。2) 編譯 沒有什麼好說的了 javac HelloWorld.java 3) 生成擴展名為h的頭文件 javah ? jni HelloWorld 頭文件的內容: /* DO NOT EDIT THIS FILE - it is machine generated */ 1. include /* Header for class HelloWorld */ 1. ifndef _Included_HelloWorld 2. define _Included_HelloWorld 3. ifdef __cplusplus extern "C" { 1. endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V * / JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); 1. ifdef __cplusplus } 1. endif 2. endif (這里我們可以這樣理解:這個h文件相當於我們在java裡面的介面,這里聲明了一個 Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然後在我們的本地方法裡面實現這個方法,也就是說我們在編寫C/C++程序的時候所使用的方法名必須和這里的一致)。4) 編寫本地方法實現和由javah命令生成的頭文件裡面聲明的方法名相同的方法。 代碼2:1 #include "jni.h" 2 #include "HelloWorld.h" 3 //#include other headers 4 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!\n"); return; } 注意代碼2中的第1行,需要將jni.h(該文件可以在%JAVA_HOME%/include文件夾下面找到)文件引入,因為在程序中的JNIEnv、 jobject等類型都是在該頭文件中定義的;另外在第2行需要將HelloWorld.h頭文件引入(我是這么理解的:相當於我們在編寫java程序的時候,實現一個介面的話需要聲明才可以,這里就是將HelloWorld.h頭文件裡面聲明的方法加以實現。當然不一定是這樣)。然後保存為 HelloWorldImpl.c就ok了。5) 生成動態庫 這里以在Windows中為例,需要生成dll文件。在保存HelloWorldImpl.c文件夾下面,使用VC的編譯器cl成。 cl -I%java_home%\include -I%java_home%\include\win32 -LD HelloWorldImp.c -Fehello.dll 注意:生成的dll文件名在選項-Fe後面配置,這里是hello,因為在HelloWorld.java文件中我們loadLibary的時候使用的名字是hello。當然這里修改之後那裡也需要修改。另外需要將-I%java_home%\include -I%java_home%\include\win32參數加上,因為在第四步裡面編寫本地方法的時候引入了jni.h文件。6) 運行程序 java HelloWorld就ok.下面是一個簡單的例子實現列印一句話的功能,但是用的c的printf最終實現。一般提供給java的jni介麵包括一個so文件(封裝了c函數的實現)和一個java文件(需要調用path的類)。1. JNI的目的是使java方法中能夠調用c實現的一些函數,比如以下的java類,就需要調用一個本地函數testjni(一般聲明為private native類型),首先需要創建文件weiqiong.java,內容如下:class weiqiong { static { System.loadLibrary("testjni");//載入靜態庫,test函數在其中實現 } private native void testjni(); //聲明本地調用 public void test() { testjni(); } public static void main(String args[]) { weiqiong haha = new weiqiong(); haha.test(); } }2.然後執行javac weiqiong.java,如果沒有報錯,會生成一個weiqiong.class。3.然後設置classpath為你當前的工作目錄,如直接輸入命令行:set classpath = weiqiong.class所在的完整目錄(如 c:\test)再執行javah weiqiong,會生成一個文件weiqiong.h文件,其中有一個函數的聲明如下:JNIEXPORT void JNICALL Java_weiqiong_testjni (JNIEnv *, jobject);4.創建文件testjni.c將上面那個函數實現,內容如下:1. include2. includeJNIEXPORT void JNICALL Java_weiqiong_testjni (JNIEnv *env, jobject obj) { printf("haha---------go into c!!!\n"); }5.為了生成.so文件,創建makefile文件如下:libtestjni.so:testjni.o makefile gcc -Wall -rdynamic -shared -o libtestjni.so testjni.o testjni.o:testjni.c weiqiong.h gcc -Wall -c testjni.c -I./ -I/usr/java/j2sdk1.4.0/include -I/usr/java/j2sdk1.4.0/include/linux cl: rm -rf *.o *.so 注意:gcc前面是tab空,j2sdk的目錄根據自己裝的j2sdk的具體版本來寫,生成的so文件的名字必須是loadLibrary的參數名前加「lib」。6.export LD_LIBRARY_PATH=.,由此設置library路徑為當前目錄,這樣java文件才能找到so文件。一般的做法是將so文件到本機的LD_LIBRARY_PATH目錄下。7.執行java weiqiong,列印出結果:「haha---------go into c!!!」在首次使用JNI的時候有些疑問,後來在使用中一一解決,下面就是這些問題的備忘:1。 java和c是如何互通的?其實不能互通的原因主要是數據類型的問題,jni解決了這個問題,例如那個c文件中的jstring數據類型就是java傳入的String對象,經過jni函數的轉化就能成為c的char*。對應數據類型關系如下表:Java 類型 本地c類型 說明 boolean jboolean 無符號,8 位 byte jbyte 無符號,8 位 char jchar 無符號,16 位 short jshort 有符號,16 位 int jint 有符號,32 位 long jlong 有符號,64 位 float jfloat 32 位 double jdouble 64 位 void void N/AJNI 還包含了很多對應於不同 Java 對象的引用類型如下圖:2. 如何將java傳入的String參數轉換為c的char*,然後使用?java傳入的String參數,在c文件中被jni轉換為jstring的數據類型,在c文件中聲明char* test,然後test = (char*)(*env)->GetStringUTFChars(env, jstring, NULL);注意:test使用完後,通知虛擬機平台相關代碼無需再訪問:(*env)->ReleaseStringUTFChars(env, jstring, test);3. 將c中獲取的一個char*的buffer傳遞給java?這個char*如果是一般的字元串的話,作為string傳回去就可以了。如果是含有』\0』的buffer,最好作為bytearray傳出,因為可以制定的length,如果到string,可能到』\0』就截斷了。有兩種方式傳遞得到的數據:一種是在jni中直接new一個byte數組,然後調用函數(*env)->SetByteArrayRegion(env, bytearray, 0, len, buffer);將buffer的值到bytearray中,函數直接return bytearray就可以了。一種是return錯誤號,數據作為參數傳出,但是java的基本數據類型是傳值,對象是傳遞的引用,所以將這個需要傳出的byte數組用某個類包一下,如下:class RetObj { public byte[] bytearray; } 這個對象作為函數的參數retobj傳出,通過如下函數將retobj中的byte數組賦值便於傳出。代碼如下: jclass cls; jfieldID fid; jbyteArray bytearray; bytearray = (*env)->NewByteArray(env,len); (*env)->SetByteArrayRegion(env, bytearray, 0, len, buffer); cls = (*env)->GetObjectClass(env, retobj); fid = (*env)->GetFieldID(env, cls, "retbytes", "[B"]); (*env)->SetObjectField(env, retobj, fid, bytearray);4. 不知道佔用多少空間的buffer,如何傳遞出去呢?在jni的c文件中new出空間,傳遞出去。java的數據不初始化,指向傳遞出去的空間即可。 你還費解嗎</SPAN></SPAN></SPAN></SPAN>
</p>

⑤ java通過jni怎麼調用c

只提供思路,自己去摸索,這樣才能吧知識轉化為自己的

1、編譯一個class類 裡面定義一個函數,注意要用native關鍵字,這是 jni入口的標志

比如 public int native jniSum(int a, int b) ;

不需要實現這個函數,像定義介面一樣。

2、使用jdk裡面的一個工具 exe,叫什麼 jnih.exe 忘了。敲命令通過這個class 生成一個同名的 .h 文件 .h 裡面會包含包路徑的。

3、然後你就可以自己寫 C/C++代碼,實現 .h里 生成的 jniSum的 C版本的函數了

4,然後將這個C/C++的代碼編譯生成一個 dll 比如名字叫 LibJniSum.dll

5,在你的 class類里,加入靜態引用

static {
System.loadLibrary("LibJniSum") ;//不要 後綴。

}

只要程序找得到你的 dll,就會自動載入dll
然後你就可以直接調用你的 jniSum了

⑥ 怎樣用 jni來交互java與 c/c++

JNI是Java Native Interface的縮寫,中文為JAVA本地調用。使用JNI可以很方便的用我們的Java程序調用C/C++程序。很多時候,某些功能用Java無法實現,比如說涉及到底層驅動的一些功能,這時候我們就可以利用JNI來調用C或者C++程序來實現,這就是JNI的強大之處。但是JNI也有它的缺點,使用java與本地已編譯的代碼交互,通常會喪失平台可移植性。
下面是一個JNI例子,調用C++輸出"hello world":

第一步:創建Java類,在裡面定義一個本地方法(用native關鍵字修飾的方法)
public native void sayHello();
第二步:使用javah命令(javah 類的全路徑)生成本地方法的C++頭文件
在DOS窗口中進入工程所在目錄,然後執行javah com.test.TestNative命令,執行完之後就會在當前目錄生成一個後綴名為.h的頭文件,如com_test_TestNative.h,這個頭文件是根據包名和類名來命名的。

1 /* DO NOT EDIT THIS FILE - it is machine generated */
2 #include <jni.h>
3 /* Header for class com_test_TestNative */
4
5 #ifndef _Included_com_test_TestNative
6 #define _Included_com_test_TestNative
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 /*
11 * Class: com_test_TestNative
12 * Method: sayHello
13 * Signature: ()V
14 */
15 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello
16 (JNIEnv *, jobject);
17
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif

15、16行是對TestNative類中的本地方法sayHello()的聲明。這個h文件相當於我們在java裡面的介面,這里聲明了一個 Java_com_test_TestNative_sayHello (JNIEnv *, jobject);方法,然後在我們的本地方法裡面實現這個方法,也就是說我們在編寫C/C++程序的時候所使用的方法名必須和這里的一致。
第三步:編寫C/C++本地代碼,生成動態鏈接庫文件
首先在VC6.0(當然也可以用其他工具)中創建一個dll工程---Win32 Dynamic-Link Library工程。然後將上面生成的頭文件com_test_TestNative.h添加到該工程中,然後創建一個源文件引用該頭文件並且實現頭文件中本地函數的功能:

1 #include<iostream.h>
2 #include"com_test_TestNative.h"
3
4 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello(JNIEnv *env, jobject obj)
5 {
6 cout<<"hello world!"<<endl;
7 }

這里因為com_test_TestNative.h中引入了jni.h所以要將jni.h加入到VC6.0安裝目錄下的Include目錄中。jni.h在JDK安裝目錄下的include中,同時得件include/win32中的兩個頭文件jawt_md.h、jni_md.h也導入到VC6.0中。
將所依賴的頭文件導入之後,我們就可以構建該工程了,按F7就行了,完了會在工程目錄中的Degug目錄下生成一個動態鏈接庫文件,我這里生成的是NativeCode.dll。我們就可以將該dll文件拷貝到環境變數path所包含的目錄下給咱們的Java程序調用了,為了方便,我們也可以將dll所在的工程目錄加入到環境變數path中去,這樣可以避免每次都要拷貝的麻煩。注意修改環境變數之後要重啟myeclipse。

第四步:Java調用本地函數

1 package com.test;
2
3 public class TestNative {
4 public native void sayHello();
5
6 /**
7 * @param args
8 */
9 public static void main(String[] args) {
10 System.loadLibrary("NativeCode");
11 TestNative tNative = new TestNative();
12 tNative.sayHello();
13 }
14 }

第10行是載入動態鏈接庫,JVM只需要載入一次就可以調用了,「NativeCode」是上面生成的動態鏈接庫的名字,不含後綴名。
運行該程序,成功列印輸出了"hello world"。

⑦ 怎麼樣在Java程序中調用c/c++編譯器進行c/c++的編譯

可以調用的,java有一種技術叫JNI,就是為了調用C/C++,至於例子嘛是這樣的: 01. public class testdll 02. { 03. static 04. { 05. System.loadLibrary("goodluck"); 06. } 07. public native static int get(); 08. 09. public native static void set(int i); 10. public static void main(String args) 11. { 12. testdll test = new testdll(); 13. test.set(10); 14. System.out.println(test.get()); 15. } 16. 17. } 用javac testdll.java編譯它,會生成testdll.class。 再用javah testdll,則會在當前目錄下生成testdll.h文件,這個文件需要被C/C++程序調用來生成所需的庫文件。 二、C/C++中所需要做的工作 對於已生成的.h頭文件,C/C++所需要做的,就是把它的各個方法具體的實現。然後編譯連接成庫文件即可。再把庫文件拷貝到JAVA程序的路徑下面,就可以用JAVA調用C/C++所實現的功能了。 好,下面我們用testdll.cpp文件具體實現這兩個函數: 01. #include "testdll.h" 02. int i = 0; 03. JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass) 04. { 05. return i; 06. } 07. JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j) 08. { 09. i = j; 10. } 編譯連接成庫文件,本例是在WINDOWS下做的,生成的是DLL文件。並且名稱要與JAVA中需要調用的一致,這里就是goodluck.dll http://ask.wangmeng.cn/question/88

⑧ 關於jni方法調用本地vc++程序,c++程序中含有包含的頭文件和lib庫文件,請問jni方法怎麼正確調用這個程序

jni的HelloWorld:
1.編寫java部分,本地方法用關鍵字native表示,不用帶方法體, 如:private native void helloworld();
2.使用命令行,linux與windos一樣,在.java文件目錄中使用javac,將其專為.class文件。若java部分帶包,則在包的 上一級使用javah,如bin\com\fhy\jnitest\HelloWorld.class 則在bin\下使用javah並且要帶包名,如javah com.fhy.HelloWorld,若無包則在.class目錄中使 用。
3.將生成的.h文件放入vc的工程中並引入,在本地方法實現時,對於vc,在方法實現前部加入extern 「C」,使編譯器用C編譯器編 譯,而不是C++,後者可能導致函數名發生變化
4.將生成的.dll放入java工程目錄中,jni部分完成

c++的沒做過,應該是完全一樣只用修改extern部分吧

⑨ jni 調用c和c++的區別

沒有本質區別。但是要注意C++的name mangling的問題。

JNI通過函數名找函數入口,執行函數里的內容。這和函數用什麼語言生成的並沒有關系。只要保證函數名稱符合JNI的協議。而C++要注意的是C++默認生成的函數名稱和你寫在源文件中的名稱並不相同,因為C++要處理函數重載,會在函數名稱中加上參數信息,這稱為name mangling。解決方法是定義函數時在前面加上extern "C"修飾,告訴編譯器這函數要被C調用(當然,其實是JNI),要保留源碼中的函數名。比如:
extern "C" jint Java_com_goo_Foo_bar(JNIEnv *, jobject);

另外C++下,JNIEnv等結構體是作為類存在的,其中的函數可以直接用成員函數的語法調用。

⑩ 求java JNI調用c程序

首先寫一個GoodLuck 類,裡麵包含native本地方法,這是用作C/C++實現的。也就是用C/c++實現java的native方法。
public class GoodLuck {
private String string="";
private int num;
public GoodLuck() {
}
static {
System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("goodluck");
}

public native static String getString();

public native static String getInt();

public native static void printOutString();

public native static void printOutInt();

public static void main(String args[]){
GoodLuck gl = new GoodLuck();
gl.getString();
gl.getInt();
gl.printOutString();
gl.printOutInt();
}
}
然後用 javac命令運行GoodLuck.java文件,生成GoodLuck.class文件:javac GoodLuck.java,然後再用javah運行GoodLuck.class文件:javah GoodLuck。生成GoodLuck.h。GoodLuck.h的內容為:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class GoodLuck */

#ifndef _Included_GoodLuck
#define _Included_GoodLuck
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: GoodLuck
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_GoodLuck_getString
(JNIEnv *, jclass);

/*
* Class: GoodLuck
* Method: getInt
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_GoodLuck_getInt
(JNIEnv *, jclass);

/*
* Class: GoodLuck
* Method: printOutString
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_GoodLuck_printOutString
(JNIEnv *, jclass);

/*
* Class: GoodLuck
* Method: printOutInt
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_GoodLuck_printOutInt
(JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

然後用VC6.0新建工程testdll(注意:工程為MFC AppWizard(dll)工程)
然後記得將GoodLuck.h引入,還有jni.h(在jdk目錄下),最後用C++實現這幾個方法,編譯後找到生成的dll文件,重命名為goodluck.dll,復制該dll文件與GoodLuck.class同目錄下,運行java GoodLuck,就可以了。

熱點內容
java返回this 發布:2025-10-20 08:28:16 瀏覽:705
製作腳本網站 發布:2025-10-20 08:17:34 瀏覽:968
python中的init方法 發布:2025-10-20 08:17:33 瀏覽:676
圖案密碼什麼意思 發布:2025-10-20 08:16:56 瀏覽:828
怎麼清理微信視頻緩存 發布:2025-10-20 08:12:37 瀏覽:737
c語言編譯器怎麼看執行過程 發布:2025-10-20 08:00:32 瀏覽:1076
郵箱如何填寫發信伺服器 發布:2025-10-20 07:45:27 瀏覽:308
shell腳本入門案例 發布:2025-10-20 07:44:45 瀏覽:188
怎麼上傳照片瀏覽上傳 發布:2025-10-20 07:44:03 瀏覽:875
python股票數據獲取 發布:2025-10-20 07:39:44 瀏覽:829