java調用c介面
A. java用jna調用c語言dll介面中的回調函數怎麼寫
簡單的你會寫,那就好辦,直接上代碼
{
{
/**
*登錄回調
*/
voidinvoke(StringuserId,longretCode,StringretMsg);
}
/**
*注冊一個登錄回調方法.此方法是dll提供的
*/
voidRegisterLoginReply(LoginReplyloginReply);
}
/**
*實現登錄回調方法
*/
.LoginReply{
@Override
publicvoidinvoke(StringuserId,longretCode,StringretMsg){
log.info("登錄回調方法:{},{},{}",userId,retCode,retMsg);
}
}
//設置登錄回調
api.RegisterLoginReply(loginReplyCallBack);
B. Java如何調用C語言代碼
Java Native Interface(JNI)是Java語言的本地編程介面,是J2SDK的一部分。在java程序中,我們可以通過JNI實現一些用java語言不便實現的功能。通常有以下幾種情況我們需要使用JNI來實現。 標準的java類庫沒有提供你的應用程序所需要的功能,通常這些功能是平台相關的 你希望使用一些已經有的類庫或者應用程序,而他們並非用java語言編寫的 程序的某些部分對速度要求比較苛刻,你選擇用匯編或者c語言來實現並在java語言中調用他們 下面我們開始編寫HelloWorld程序,由於涉及到要編寫c/c++代碼因此我們會在開發中使用Microsoft VC++工具。編寫java代碼,我們在硬碟上建立一個hello目錄作為我們的工作目錄,首先我們需要編寫自己的java代碼,在java代碼中我們會聲明native方法,代碼非常簡單。如下所示 class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("hello"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } } 注意我們的displayHelloWorld()方法的聲明,它有一個關鍵字native,表明這個方法使用java以外的語言實現。方法不包括實現,因為我們要用c/c++語言實現它。注意System.loadLibrary("hello")這句代碼,它是在靜態初始化塊中定義的,系統用來裝載hello共享庫,這就是我們在後面生成的hello.dll(如果在其他的操作系統可能是其他的形式,比如hello.so) 編譯java代碼 javac HelloWorld.java 生成HelloWorld.class文件 創建.h文件 這一步中我們要使用javah命令生成.h文件,這個文件要在後面的c/c++代碼中用到,我們運行 javah HelloWorld。這樣我們可以看到在相同目錄下生成了一個HelloWorld.h文件,文件內容如下 在此我們不對他進行太多的解釋。 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif 編寫本地實現代碼 在這部分我們要用C/C++語言實現java中定義的方法,我們在VC++中新建一個Project,然後創建一個HelloWorldImp.cpp文件,內容如下 #include <jni.h> #include "HelloWorld.h" #include <stdio.h> JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!\n"); return; } 注意我們這里include了 jni.h和剛才得到的HelloWorld.h文件。因此你要在VC++裡面設置好,jni.h在JAVA_HOME/include裡面。編譯通過後再生成hello.dll文件。 運行java程序 把上面生成的hello.dll文件復制到我們的工作目錄,這時候我們的目錄中包括HelloWorld.java,HelloWorld.class和hello.dll文件。運行java HelloWorld命令,則可在控制台看到Hello world| 的輸出了。運行VC++; 文件---新建---選「win32 console application」(控制台程序)---在右方設置好路徑並輸入工程名---確定 接下來的幾個提示框點確定就行了,那是提示是否要用VC++提供的框架之類的 在左邊的工作空間中選「FILEVIEW」標簽項,點開「+」號,右鍵點擊「SOURCE FILES」,選「添加文件到目錄」,此即添加你要建立的C++源程序文件,會提示你沒有文件,是否添加,你點是,輸入文件名保存就OK了 然後SOURCE FILES下就出現了你剛才建立的*.CPP文件,雙擊,輸入代碼. 以下就是點」組建」菜單中的」編譯」、」組建」等命令進行調試了。 相信你會了。 http://hi..com/%C7%E9%D4%B5and%D3%D1%D2%EA/blog/item/34084645e8560f23cefca3b7.html
C. 鍐欎竴孌礿ava浠g爜錛岃皟鐢╟紼嬪簭錛岄兘鏈変粈涔堝姙娉
JAVA浠ュ叾璺ㄥ鉤鍙扮殑鐗規ф繁鍙椾漢浠鍠滅埍錛岃屽張姝g敱浜庡畠鐨勮法騫沖彴鐨勭洰鐨勶紝浣垮緱瀹冨拰鏈鍦版満鍣ㄧ殑鍚勭嶅唴閮ㄨ仈緋誨彉寰楀緢灝戱紝綰︽潫浜嗗畠鐨勫姛鑳姐傝В鍐矹AVA瀵規湰鍦版搷浣滅殑涓縐嶆柟娉曞氨鏄疛NI銆
JAVA閫氳繃JNI璋冪敤鏈鍦版柟娉曪紝鑰屾湰鍦版柟娉曟槸浠ュ簱鏂囦歡鐨勫艦寮忓瓨鏀劇殑錛堝湪WINDOWS騫沖彴涓婃槸DLL鏂囦歡褰㈠紡錛屽湪UNIX鏈哄櫒涓婃槸SO鏂囦歡褰㈠紡錛夈傞氳繃璋冪敤鏈鍦扮殑搴撴枃浠剁殑鍐呴儴鏂規硶錛屼嬌JAVA鍙浠ュ疄鐜板拰鏈鍦版満鍣ㄧ殑緔у瘑鑱旂郴錛岃皟鐢ㄧ郴緇熺駭鐨勫悇鎺ュ彛鏂規硶銆
綆鍗曚粙緇嶅強搴旂敤濡備笅錛
涓銆丣AVA涓鎵闇瑕佸仛鐨勫伐浣
鍦↗AVA紼嬪簭涓錛岄栧厛闇瑕佸湪綾諱腑澹版槑鎵璋冪敤鐨勫簱鍚嶇О錛屽備笅錛
static {
System.loadLibrary(鈥済oodluck鈥);
}
鍦ㄨ繖閲岋紝搴撶殑鎵╁睍鍚嶅瓧鍙浠ヤ笉鐢ㄥ啓鍑烘潵錛岀┒絝熸槸DLL榪樻槸SO錛岀敱緋葷粺鑷宸卞垽鏂銆
榪橀渶瑕佸瑰皢瑕佽皟鐢ㄧ殑鏂規硶鍋氭湰鍦板0鏄庯紝鍏抽敭瀛椾負native銆傚苟涓斿彧闇瑕佸0鏄庯紝鑰屼笉闇瑕佸叿浣撳疄鐜般傚備笅錛
public native static void set(int i);
public native static int get();
鐒跺悗緙栬瘧璇JAVA紼嬪簭鏂囦歡錛岀敓鎴怌LASS錛屽啀鐢↗AVAH鍛戒護錛孞NI灝變細鐢熸垚C/C++鐨勫ご鏂囦歡銆
渚嬪傜▼搴弔estdll.java錛屽唴瀹逛負錛
public class testdll
{
static
{
System.loadLibrary("goodluck");
}
public native static int get();
public native static void set(int i);
public static void main(String[] args)
{
testdll test = new testdll();
test.set(10);
System.out.println(test.get());
}
}
鐢╦avac testdll.java緙栬瘧瀹冿紝浼氱敓鎴恡estdll.class銆
鍐嶇敤javah testdll錛屽垯浼氬湪褰撳墠鐩褰曚笅鐢熸垚testdll.h鏂囦歡錛岃繖涓鏂囦歡闇瑕佽獵/C++紼嬪簭璋冪敤鏉ョ敓鎴愭墍闇鐨勫簱鏂囦歡銆
浜屻丆/C++涓鎵闇瑕佸仛鐨勫伐浣
瀵逛簬宸茬敓鎴愮殑.h澶存枃浠訛紝C/C++鎵闇瑕佸仛鐨勶紝灝辨槸鎶婂畠鐨勫悇涓鏂規硶鍏蜂綋鐨勫疄鐜般傜劧鍚庣紪璇戣繛鎺ユ垚搴撴枃浠跺嵆鍙銆傚啀鎶婂簱鏂囦歡鎷瘋礉鍒癑AVA紼嬪簭鐨勮礬寰勪笅闈錛屽氨鍙浠ョ敤JAVA璋冪敤C/C++鎵瀹炵幇鐨勫姛鑳戒簡銆
鎺ヤ笂渚嬪瓙銆傛垜浠鍏堢湅涓涓媡estdll.h鏂囦歡鐨勫唴瀹癸細
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class testdll */
#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: testdll
* Method: get
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_testdll_get
(JNIEnv *, jclass);
/*
* Class: testdll
* Method: set
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_testdll_set
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
鍦ㄥ叿浣撳疄鐜扮殑鏃跺欙紝鎴戜滑鍙鍏沖績涓や釜鍑芥暟鍘熷瀷
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);
鍜
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
榪欓噷JNIEXPORT鍜孞NICALL閮芥槸JNI鐨勫叧閿瀛楋紝琛ㄧず姝ゅ嚱鏁版槸瑕佽獼NI璋冪敤鐨勩傝宩int鏄浠JNI涓轟腑浠嬩嬌JAVA鐨剗nt綾誨瀷涓庢湰鍦扮殑int娌熼氱殑涓縐嶇被鍨嬶紝鎴戜滑鍙浠ヨ嗚屼笉瑙侊紝灝卞綋鍋歩nt浣跨敤銆傚嚱鏁扮殑鍚嶇О鏄疛AVA_鍐嶅姞涓妀ava紼嬪簭鐨刾ackage璺寰勫啀鍔犲嚱鏁板悕緇勬垚鐨勩傚弬鏁頒腑錛屾垜浠涔熷彧闇瑕佸叧蹇冨湪JAVA紼嬪簭涓瀛樺湪鐨勫弬鏁幫紝鑷充簬JNIEnv*鍜宩class鎴戜滑涓鑸娌℃湁蹇呰佸幓紕板畠銆
濂斤紝涓嬮潰鎴戜滑鐢╰estdll.cpp鏂囦歡鍏蜂綋瀹炵幇榪欎袱涓鍑芥暟錛
#include "testdll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)
{
return i;
}
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)
{
i = j;
}
緙栬瘧榪炴帴鎴愬簱鏂囦歡錛屾湰渚嬫槸鍦╓INDOWS涓嬪仛鐨勶紝鐢熸垚鐨勬槸DLL鏂囦歡銆傚苟涓斿悕縐拌佷笌JAVA涓闇瑕佽皟鐢ㄧ殑涓鑷達紝榪欓噷灝辨槸goodluck.dll
鎶奼oodluck.dll鎷瘋礉鍒皌estdll.class鐨勭洰褰曚笅錛宩ava testdll榪愯屽畠錛屽氨鍙浠ヨ傚療鍒扮粨鏋滀簡銆
D. 浠涔堟牱鐨勬妧鏈鑳借﹋ava璋冪敤c璇璦鐨勪唬鐮
java琚緙栬瘧鎴愬瓧鑺傜爜鍚庣敱JVM瑙i噴鎵ц岋紝java瑕佽皟鐢–璇璦鍐欑殑紼嬪簭錛岄偅涔堝氨蹇呴』閫氳繃JVM璋冪敤錛宩ava鍛婅瘔JVM鎴戣佽皟鐢ㄦ湰鍦版搷浣滅郴緇熺殑閭d釜紼嬪簭孌碉紙濡俤ll錛夊苟瑕佹眰榪斿洖涓涓緇撴灉銆傞氳繃JVM璋冪敤鏈鍦扮▼搴忕殑鎶鏈灝辨槸JNI錛宩ava Native interface(鏈鍦版帴鍙f妧鏈)銆
java鏄閫氳繃鉶氭嫙鏈哄疄鐜拌法騫沖彴鎶鏈鐨勶紝鍥犳よ佽皟鐢ㄦ湰鍦版搷浣滅郴緇熺浉鍏崇殑浠g爜錛屽氨蹇呴』閲囩敤JNI鎶鏈銆傝岃繖灝卞艱嚧浜咼AVA涓庢搷浣滅郴緇熺殑涓縐嶅簲鐢ㄧ粦瀹氾紝澶卞幓浜嗚法騫沖彴鐨勭壒鑹層傚綋鐒舵垜浠鍦ㄥ簲鐢ㄤ腑鍙鑳介渶瑕佷嬌鐢ㄦ湰鍦頒唬鐮佹妧鏈鏇村姞瀹規槗瀹炵幇鏌愪釜鏂規硶錛岄噰鐢ㄨ繖縐嶆柟寮忔湁鏃朵篃鏄蹇呴』鐨勩
鍏跺疄涓嶇′綘鏄鐢–榪樻槸鍏朵粬璇璦緙栬瘧鐨勪唬鐮侊紝鍙瑕佺﹀悎璋冪敤瑙勫垯錛屽氨鍙浠ュ疄鐜癹ava瀵規湰鍦扮▼搴忕殑璋冪敤銆
E. java怎麼引用c
Java調用C語言程序時,主要是涉及到操作系統底層的事件。這種時間Java無法處理,例如用戶上傳一個視頻文件,需要後台給視頻加上水印,或者後台分離視頻流和音頻流。只能通過調用C語言處理。
使用Java如何去調用C語言的介面呢?使用Java的JNI技術。
具體調用步驟如下:
1.首先創建Java文件 HelloJni.java ,並創建native方法。
2.編譯Java文件並生成java頭文件。
3.創建C語言文件,HelloWorld.c。
4.生成動態鏈接庫文件 libhello.so。
5.設置動態鏈接庫文件的目錄。
6.把剛才生成的so文件拷貝到/home/lib下,然後執行class文件。
F. JAVA調用C語言發布的webservice介面
Java調用WebService可以直接使用Apache提供的axis.jar自己編寫代碼,或者利用Eclipse自動生成WebService Client代碼,利用其中的Proxy類進行調用。理論上是一樣的,只不過用Eclipse自動生成代碼省事些。
1、編寫代碼方式:
packagecom.yun.test;
importjava.rmi.RemoteException;
importorg.apache.axis.client.Call;
importorg.apache.axis.client.Service;
importorg.apache.axis.message.PrefixedQName;
importorg.apache.axis.message.SOAPHeaderElement;
importcom.cezanne.golden.user.Exception;
importcom.cezanne.golden.user.UserManagerServiceProxy;
importjavax.xml.namespace.QName;
importjava.net.MalformedURLException;
importjavax.xml.rpc.ServiceException;
importjavax.xml.soap.Name;
importjavax.xml.soap.SOAPException;
publicclasstestWebService{
publicstaticStringgetResult()throwsServiceException,MalformedURLException,RemoteException,SOAPException
{
//標識WebService的具體路徑
Stringendpoint="WebService服務地址";
//創建Service實例
Serviceservice=newService();
//通過Service實例創建Call的實例
Callcall=(Call)service.createCall();
//將WebService的服務路徑加入到call實例之中.
call.setTargetEndpointAddress(newjava.net.URL(endpoint));//為Call設置服務的位置
//由於需要認證,故需要設置調用的SOAP頭信息。
NameheaderName=newPrefixedQName(newQName("發布的wsdl里的targetNamespace里的url","string_itemName"));
org.apache.axis.message.SOAPHeaderElementheader=newSOAPHeaderElement(headerName);
header.addTextNode("blablabla");
call.addHeader(header);
//=newSOAPHeaderElement("發布的wsdl里的targetNamespace里的url","SoapHeader");
//soapHeaderElement.setNamespaceURI("發布的wsdl里的targetNamespace里的url");
//try
//{
//soapHeaderElement.addChildElement("string_itemName").setValue("blablabla");
//}
//catch(SOAPExceptione)
//{
//e.printStackTrace();
//}
//call.addHeader(soapHeaderElement);
//調用WebService的方法
org.apache.axis.description.OperationDescoper;
org.apache.axis.description.ParameterDescparam;
oper=neworg.apache.axis.description.OperationDesc();
oper.setName("opName");
param=neworg.apache.axis.description.ParameterDesc(newjavax.xml.namespace.QName("","arg0"),org.apache.axis.description.ParameterDesc.IN,newjavax.xml.namespace.QName(","string"),java.lang.String.class,false,false);
param.setOmittable(true);
oper.addParameter(param);
param=neworg.apache.axis.description.ParameterDesc(newjavax.xml.namespace.QName("","arg1"),org.apache.axis.description.ParameterDesc.IN,newjavax.xml.namespace.QName(","string"),java.lang.String.class,false,false);
param.setOmittable(true);
oper.addParameter(param);
param=neworg.apache.axis.description.ParameterDesc(newjavax.xml.namespace.QName("","arg2"),org.apache.axis.description.ParameterDesc.IN,newjavax.xml.namespace.QName(","string"),java.lang.String.class,false,false);
param.setOmittable(true);
oper.addParameter(param);
oper.setReturnType(newjavax.xml.namespace.QName(","string"));
oper.setReturnClass(java.lang.String.class);
oper.setReturnQName(newjavax.xml.namespace.QName("","return"));
oper.setStyle(org.apache.axis.constants.Style.WRAPPED);
oper.setUse(org.apache.axis.constants.Use.LITERAL);
oper.addFault(neworg.apache.axis.description.FaultDesc(
newjavax.xml.namespace.QName("發布的wsdl里的targetNamespace里的url","Exception"),
"Exception",
newjavax.xml.namespace.QName("發布的wsdl里的targetNamespace里的url","Exception"),
true
));
call.setOperation(oper);
call.setOperationName(newjavax.xml.namespace.QName("發布的wsdl里的targetNamespace里的url","opName"));
//調用WebService,傳入參數
Stringres=(String)call.invoke(newObject[]("arg0","arg1"));
System.out.println("===============");
returnres;
}
/**
*@paramargs
*/
publicstaticvoidmain(String[]args){
try{
System.out.println(getResult());
}catch(MalformedURLExceptione){
e.printStackTrace();
}catch(RemoteExceptione){
e.printStackTrace();
}catch(ServiceExceptione){
e.printStackTrace();
}catch(SOAPExceptione){
e.printStackTrace();
}
}
}
2、利用Eclipse自動生成WebService client代碼就容易多了:
首先,new project,選擇other,在輸入框中輸入Web Service Client,選中搜索後的結果,點擊Next,在Service definition中輸入 WebService的發布地址,點擊Finish
這樣,WebService Client代碼已經生成好了。
接下來寫一個Test類,在main函數中輸入如下代碼:
Stringendpoint="伺服器的WebService的地址";
YourWebServiceNameProxyumsp=newYourWebServiceNameProxy(endpoint);
try{
StringresultStr=umsp.opMethod("arg0","arg1");
System.out.println(resultStr);
}catch(Exceptione){
System.out.println("異常");
e.printStackTrace();
}catch(RemoteExceptione){
System.out.println("RemoteException異常");
e.printStackTrace();
}
G. 用Java怎麼調用C語言已經編寫好的DLL
1.用System.getProperty("user.dir"),獲取程序的路徑,估計你的應該是 E:\\測試程序不清楚列印一下就可以了。System.getProperty("user.dir") + "\\DLL\\CardAPI"2.unsigned char 用char就可以了unsigned int 用int就可以了,java的int值很大.....C的無符號的記得是65535 unsigned char*、和unsigned int* 這兩個是指針,第一個是取1位地址內容的,第二個根據系統而定,一般是取4位地址值的,用java 的String對應,應該可以 。
H. 怎樣用 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"。