用Java调用C# 的WebService接口
用Java调用C# 的WebService接口
这是一个用Java调用C#版WebService接口的例子:
C#接口:
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Services.Description;
[WebService(Namespace = " / " )]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
public Service () ... {
// 如果使用设计的组件,请取消注释以下行
// InitializeComponent();
}
[SoapRpcMethod(Action = " /Add " , RequestNamespace = " /T " , ResponseNamespace = " /T " , Use = SoapBindingUse.Literal)]
[WebMethod]
public int Add( int a, int b)
... {
return a + b;
}
[SoapRpcMethod(Action = " /Hello " , RequestNamespace = " /T " , ResponseNamespace = " /T " , Use = SoapBindingUse.Literal)]
[WebMethod]
public String HelloWorld()
... {
return " Hello, world! " ;
}
}
...
Java调用这个Webservice中的Add方法和HelloWorld方法:
1.有参方法:Add
public static void addTest() {
try ... {
Integer i = 1 ;
Integer j = 2 ;
// WebService URL
String service_url = " http://localhost:4079/ws/Service.asmx " ;
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new .URL(service_url));
// 设置要调用的方法
call.setOperationName( new QName( " /T " , " Add " ));
// 该方法需要的参数
call.addParameter( " a " , org.apache.axis.encoding.XMLType.XSD_INT,
javax.xml.rpc.ParameterMode.IN);
call.addParameter( " b " , org.apache.axis.encoding.XMLType.XSD_INT,
javax.xml.rpc.ParameterMode.IN);
// 方法的返回值类型
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_INT);
call.setUseSOAPAction( true );
call.setSOAPActionURI( " /Add " );
// 调用该方法
Integer res = (Integer)call.invoke(
new Object[] ... {
i, j
}
);
System.out.println( " Result: " + res.toString());
} catch (Exception e) ... {
System.err.println(e);
}
} ...
运行,结果返回:Result:3
2.无参方法:HelloWorld
public static void helloTest() {
try ... {
String endpoint = " http://localhost:4079/ws/Service.asmx " ;
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new .URL(endpoint));
call.setOperationName( new QName( " /T " , " HelloWorld " ));
call.setUseSOAPAction( true );
call.setSOAPActionURI( " /Hello " );
String res = (String)call.invoke(
new Object[] ... {
null
}
);
System.out.println( " Result: " + res);
} catch (Exception e) ... {
System.err.println(e.toString());
}
} ...
可以看到,调用无参的webservice和有参的基本相同,不过无参调用时,不需要调用Call的addParameter方法和setReturnType方法
执行结果返回:Hello, world!。
java调用c方法
java调用c方法Java调用C方法在Java开发中,有时候会需要调用C语言编写的库或者方法来提供底层的功能支持或者优化性能。
本文将详细介绍Java调用C方法的各种方法。
方法一:JNIJNI(Java Native Interface)是一种允许Java代码调用本地方法的标准机制。
下面是使用JNI调用C方法的步骤:1.编写C代码文件:首先需要编写C代码,包含要调用的方法的实现。
可以将C代码编写到独立的文件中,如``。
2.生成头文件:使用Java提供的javah工具生成C头文件。
在终端中执行以下命令:javah -jni这将生成com_example_文件,其中``是包含本地方法定义的Java类。
3.实现本地方法:在C代码文件中实现头文件中定义的本地方法。
4.编译本地库:使用C编译器编译C代码文件并生成本地库文件(.so文件或.dll文件)。
在终端中执行以下命令:gcc -shared -o -I${JAVA_HOME}/include -I ${JAVA_HOME}/include/linux这将生成文件,其中是C代码文件。
5.加载本地库:在Java类中使用("native")加载本地库。
6.声明本地方法:在Java类中声明使用native关键字修饰的本地方法。
7.调用本地方法:通过Java代码调用本地方法。
方法二:JNAJNA(Java Native Access)是一种简化了JNI复杂性的Java库,它提供了一种更简单的方式来调用本地方法。
下面是使用JNA调用C方法的步骤:1.引入JNA库:在Java项目中引入JNA库的依赖。
2.声明本地方法:在Java接口中声明要调用的本地方法。
3.加载本地库:使用()方法加载本地库文件。
4.调用本地方法:通过Java代码调用本地方法。
与JNI相比,JNA的使用更加简单,不需要编写繁琐的C代码和生成头文件。
在使用JNA时,需要注意本地方法的声明方式和加载本地库的方式。
java调用c方法
java调用c方法以Java调用C方法为标题,本文将介绍如何在Java程序中调用C 方法的步骤和注意事项。
通过Java调用C方法,可以充分发挥C 语言的高效性能和丰富的库函数,为Java程序提供更多的功能和灵活性。
一、C方法的封装在Java中调用C方法,首先需要将C方法封装成动态链接库(DLL)或共享库(SO)。
C语言提供了一些特殊的关键字和修饰符,用于定义C方法的接口,例如extern、__stdcall等。
在封装C方法时,需要注意以下几点:1. 定义方法的参数和返回值类型:Java和C语言的数据类型不完全一致,需要进行相应的映射。
常见的映射关系如下:- Java的int类型对应C的int类型;- Java的float类型对应C的float类型;- Java的String类型对应C的char*类型;- Java的Object类型对应C的void*类型等。
2. 调用约定:C语言有多种调用约定,如__cdecl、__stdcall等。
在封装C方法时,需要根据C方法的调用约定,选择合适的修饰符进行声明。
3. 异常处理:C语言没有内置的异常处理机制,因此在封装C方法时,需要特别注意错误处理。
可以通过返回值或传入指针参数的方式,将错误信息传递给Java程序。
二、Java中调用C方法的步骤在封装C方法后,就可以在Java程序中调用了。
下面是Java中调用C方法的基本步骤:1. 加载C库:使用System.loadLibrary()方法加载C库,将C方法所在的动态链接库加载到Java虚拟机中。
2. 定义native方法:在Java类中声明native方法,以便在Java 程序中调用C方法。
使用关键字native修饰方法,告诉编译器这个方法是由外部实现的。
3. 实现C方法:在C方法封装成的动态链接库中实现native方法的具体逻辑。
4. 编译和运行Java程序:使用javac命令将Java源文件编译成字节码文件,然后使用java命令运行Java程序。
JNI接口之java调C++简单示例
示例实现:JNI接口之java掉C实现开发环境:vs2010,eclipse1、新建eclipse工程,代码如下(建议使用高版本jdk,本人使用jdk1.8):package ;publicclass MyJni {//使用JNI的关键字native,这个关键字决定我们哪些方法能在我们的C文件中使用,只需声明,不必实现publicnativevoid display();publicnativedouble sum(double x,double y);//这个是到时候调用我们写好的c文件,现在用不上,可以先注释掉// static {//System.out.println(System.getProperty("jav a.library.path"));//System.loadLibrary("jni04Dll");// }publicstaticvoid main(String[] args) { // TODO Auto-generated method stubSystem.out.println("heheda");//到时候测试用方法现在用不上,可以先注释掉//new MyJni().display();//System.out.println(new MyJni().sum(2.0, 3.0)); }}2、先把写好的类转成.class文件,进入工程目录src目录下,cmd打开dos窗口,执行如下命令:javac java2c/thinkit/cn/MyJni.java会在.java文件同级目录生成.class文件然后把.class文件转换成头文件,dos窗口执行如下命令:Javah .MyJni会在src目录下生成我们需要的头文件,名字为java2c_thinkit_cn_MyJni.h,后面会用到3、VS2010创建动态链接库,方法新建工程,选择win32项目,选择dll、空项目,如下图;4、导入所需要的头文件,需要jdk目录C:\Java\jdk1.8.0_77\include下面的jni.h文件以及目录C:\Java\jdk1.8.0_77\include\win32下jni_md.h文件,和上面生成的java2c_thinkit_cn_MyJni.h文件(java安装路径不要有空格)新建头文件和源文件,新建头文件,名字为jni04Dll.h,内容如下:方面名是参照生成的java2c_thinkit_cn_MyJni.h这个文件里的两个方法名字写的,这里做声明,在.cpp里进行实现;JNIEXPORT void JNICALL Java_java2c_thinkit_cn_MyJni_display(JNIEnv *env,jobjectobj); JNIEXPORT jdouble JNICALL Java_java2c_thinkit_cn_MyJni_sum(JNIEnv*env,jobjectobj,jdoublea,jdouble b);void MyName();新建源文件,名字为jni04Dll.cpp,内容如下:#include"jni.h"#include"jni_md.h"#include"java2c_thinkit_cn_MyJni.h"#include<stdio.h>#include"jni04Dll.h"JNIEXPORT void JNICALL Java_java2c_thinkit_cn_MyJni_display(JNIEnv *env,jobjectobj){ printf("hello world!");MyName();return;}JNIEXPORT jdouble JNICALL Java_java2c_thinkit_cn_MyJni_sum(JNIEnv*env,jobjectobj,jdoublea,jdouble b){return a+b;}void MyName(){printf("test is successful!\n");return;}右键工程->属性->c/c++->常规,添加java2c_thinkit_cn_MyJni.h所在路径;注意需要生成64位的动态链接库,否则java调用的话会报错:然后工程文件右键->生成,在项目目录x64/debug目录下,生成.dll和.lib文件。
3、Java调用C语言(JNA法)
3、Java调⽤C语⾔(JNA法)这个⽅法挺⽅便的……(改写“⼆、Java调⽤C语⾔(JNative法)“的例⼦)⼆、在 F:\MinGW\Jna新建 Test.java:import com.sun.jna.Native;public class Test { public static void main(String[] args) { Lib lib = (Lib) Native.loadLibrary("test", Lib.class); // 例1 int re1 = lib.add(11, 9); System.out.println("例1:addresult = "+re1); // 例2 int len=3; int[] a = {11, 18, 21}; int[] b = {44, 56, 100}; int[] c = new int[3]; lib.addArray(a, b, c, len); for (int i = 0; i < len; i++) { System.out.println("例2:addArray"+(i+1)+" = "+c[i]); } // 例3 String inputString = "kun"; String outputString = lib.stringFun(inputString); System.out.println("例3:outputString = "+outputString); }}三、再新建⼀个 Lib.java:import com.sun.jna.Library;public interface Lib extends Library { int add(int a, int b); void addArray(int[] a, int[] b, int[] c,int len); String stringFun(String str1);}四、再新建⼀个 test.c:#include <stdio.h>#include <malloc.h>int add(int a, int b) { return (a + b);}void addArray(int *a,int *b,int *c,int len) { int i; for(i=0;i<len;i++) { c[i]=a[i]+b[i]; }}char* stringFun(char *str1) { printf("例3:intputString = %s\n",str1); char *str2 = (char*)malloc(sizeof(char)*17); str2 = "HG-U133_Plus_2.0"; return str2;}五、⽣成dll:⽅法⼀:如果安装了MinGWf:cd MinGW/Jnagcc -Wall -shared test.c -o test.dlljavac Test.javajava Test这时⽬录下新⽣成了test.dll、Test.class、Lib.class效果:⽅法⼆:如果安装了Rtools(注意:我是Win7系统)f:cd MinGW/JnaR CMD SHLIB test.cjavac Test.javajava Test这时⽬录下新⽣成了test.dll、test.o、Test.class、Lib.class。
【黑马程序员】jni之java调用c
【黑马程序员】jni之java调用cjava调用C步骤第一步,写java代码,,写一个natvie方法public native String getServerInfo(String path);第二步。
创建jni目录,在目录中创建test.c文件,同时将jni.h文件放入jni目录写c代码,注意方法名,并且引入jni.h#include <jni.h>#include <stdio.h>jstring Java_com_example_untitled_MyActivity_getServerInfo(JNIEnv* env, jobject thiz, jstring path) {写方法。
}注意:方法名的写法如下Java_包名_类型_方法名(jvm虚拟机的指针,调用者对象)这里生成方法名也可以通过ndk来实现的分为2步* 通过dos命令使用javac -d . Test.java 命令编译带有native方法的.java文件,这样就会在当前目录中生成一个class文件会生成com/b3a4a/jnitest/Test.class* 通过javah命令来生成例如javah com.b3a4a.jnitest.Test,会生成.h的头文件生成com_b3a4a_jnitest_T est.h 文件,方法名就在.h头文件中JNIEXPORT jstring JNICALL Java_com_b3a4a_jnitest_T est_getServerInfo (JNIEnv *, jobject);第三步,在jni目录中创建文件,andorid.mkLOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := testLOCAL_SRC_FILES := test.cLOCAL_C_INCLUDES := $(LOCAL_PATH)/includeLOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -lloginclude $(BUILD_SHARED_LIBRARY)第四步,进入命令行,进入应用程序的包的目录,执行ndk-build命令,创建Application.mk,自己填写需要的处理器型号,生成不同的so文件APP_ABI := armeabi armeabi-v7a x86第五步,将生成的libtest.so 放入lib/armeabi目录(目录不需要自己建)第六步,java代码里面,把动态链接库加载到jvm虚拟机static{System.loadLibrary("库文件名称不带前缀,后缀名");}第7步,java中直接调用native方法JNI开发的常见错误1. 写错了load的libraryng.UnsatisfiedLinkError: Couldn't load hell0: findLibrary returned null 2. Android.mk文件编写错误/jni/Android.mk:4: *** missing separator. Stop.3. LOCAL_MODULE配置不能有扩展名//jni/Android.mk:hello.so: LOCAL_MODULE_FILENAME must not contain a file extension4. c或者c++的源文件名称配置错误objs/hello/helo.o'. Stop.5. 如果使用了错误的cpu平台ng.UnsatisfiedLinkError: Couldn't load hello: findLibrary returned null添加多cpu平台的支持APP_ABI := armeabi armeabi-v7a x866. c语言方法名称错误,导致java代码无法寻找到c代码Caused by: ng.UnsatisfiedLinkError: Native method not found: com.itheima.hellojni.MainActivity.helloFromC:()Ljava/lang/String;7. 应用程序闪退06-25 07:31:46.698: I/dalvikvm(1871): #00 pc 0008ee6d /system/lib/libdvm.so06-25 07:31:46.698: I/dalvikvm(1871): #01 pc 000738ca /system/lib/libdvm.so06-25 07:31:46.698: I/dalvikvm(1871): #02 pc 000739f4 /system/lib/libdvm.so06-25 07:31:46.698: I/dalvikvm(1871): #03 pc 00038f5b /system/lib/libdvm.so06-25 07:31:46.698: I/dalvikvm(1871): #04 pc0003bdbd /system/lib/libdvm.so 要么就是c代码有逻辑错误要么编码问题,中文或者空格路径。
JAVA中通过JNI调用C程序实例教程
JAVA是跨平台的语言,但在有些时候还是不得不调用本地代码,而且这些代码通常是C/C++写的,比如一某个手机的项目,需要JAVA程序在发送短信的时候和第三方的短信服务器连接。
短信接口是用C++写的。
需要用到JNI的主体部分。
1、在JAVA类中声明一个native方法:①新建JAVA工程testNative,包名packC,类名myNative,选择包含main方法②创建native类hello;2、使用Javah命令生成包含native方法定义的C/C++头文件:①打开cmd②执行:cd 刚刚建好的.class文件的文件夹bin的位置③执行:javah 包名.类名④生成的头文件如下所示:3、按照生成的C/C++头文件来写C/C++源文件创建工程,按照指示操作!头文件剪切到nativeCpro工程目录下向工程中添加头文件在工程下新建C++源文件,添加到工程nativeCpro中将头文件中指定函数复制进源文件中,并添加参数env和obj4、将C/C++源文件编译成动态链接库JDK下的jni.h拷贝到C程序工程下,如不,编译会出错写入程序头文件的尖括号< >改为双引号””,因为不是从系统目录加载头文件,而是从用户目录加载头文件编译出错,需要去JDK目录下找寻jni_md.h头文件!找到之后复制到工程下面!再进行编译就成功了!成功运行之后生成.dll文件!5、把.dll文件加入到path环境变量下动态链接库是可直接执行的二进制代码!将.dll文件目录添加到环境变量path中,注意与之前的内容用分号;隔开6、Java类中加载.dll,然后调用声明的native方法(eclipse)加载动态链接库,创建对象调用hello()函数,并且重启eclipse,因为要重新读取环境变量,这样运行才能保证成功!最后理想的运行结果!!!!!!由于现在主流机器都是64位的,JDK也是64位的,但是VC++ 6.0生成的.dll 文件却是32位的,如果要得到这个理想结果,请将JDK卸载并安装32位JDK!完工!使用JNI的弊端:1、使用了JNI之后,这个Java Application就不能跨平台了,如果要移植到别的平台上,native代码就要重新编写!2、Java是强类型语言,在写JNI时要倍加小心!3、不到万不得已,不要用JNI。
Java调用C和C++动态链接库DLL第一步利用JNI
Java调用C/C++动态链接库DLL第一步利用JNI1.新建一个项目,创建一个类TestNative.java,然后点击run运行生成.class文件2.利用jdk自带的工具javah.exe 生成这个sayHello()这个native本地方法的头文件先进入eclipse下工程目录,进入bin目录,然后执行如下代码,编译出头文件这时候会出现一个自动生成的头文件用于我们编写C/C++代码3.利用Visual Studio2010 新建一个window控制台项目复制刚才利用javah生成的com_taobao_jni_TestNative.h到C++项目工程目录下,然后右击添加-->现有项将头文件引入到项目环境中4.添加JDK中系统头文件,如jni.h,这个头文件其实是在jdk目录下的include 目录下我们需要将jdk所需的所有头文件(包括win32下的所有头文件)复制到visual studio中VC 编译工具的include文件夹中,添加引入。
【所有头文件必须富之岛include的根目录下】这时候vs编译器就不会报错了,接下来我们新建一个NativeCode.cpp文件,复制生成的头文件里面的方法,实现此方法#include"com_taobao_jni_TestNative.h"#include<iostream>usingnamespace std;JNIEXPORT void JNICALL Java_com_taobao_jni_TestNative_sayHello (JNIEnv * env, jobjectobj) {cout<<"Hello World..."<<endl;}编译执行生成对应的dll文件,对与不同位数版本的jdk我们需要生成不同位数的dll,就如我的jdk是64位,那么我就需要编译出64位的dll,默认VS的编译指定是32bit,我们需要添加x64支持。
Linux上从Java程序中调用C函数
Linux上从Java程序中调⽤C函数 原则上来说,“100%纯Java”的解决⽅法是最好的,但有些情况下必须使⽤本地⽅法。
特别是在以下三种情况:需要访问Java平台⽆法访问的系统特性和设备;通过基准测试,发现Java代码⽐其他语⾔编写的等价代码慢得多;其他语⾔编写的代码已经经过⼤量测试和调试,并且知道如何将其导出到所有的⽬标平台上。
Java平台有⼀个⽤于和本地C、C++代码进⾏互操作的API,称为Java本地接⼝(JNI)。
下⾯将举例讨论Linux平台下的JNI编程。
1. 创建java类⽂件 创建⼀个nativeTest包,在包下新建HelloNative.java⽂件。
1package nativeTest;23/**4 * Created by jiax on 2016/12/30.5*/6public class HelloNative {7// 静态初始化代码块,保证虚拟机在第⼀次使⽤该类时就会装载库8static {9 System.loadLibrary( "HelloNative" );10 }1112// native 关键字表⽰本地⽅法,提醒编译器该⽅法将在外部定义13public static native void greeting();1415// 测试greeting()函数16public static void main(String[] args) {17 greeting();18 }19 }2. ⽣成.h头⽂件 使⽤以下命令⽣成⼀个C的头⽂件,nativeTest_HelloNative.h1 javac HelloNative.java2 cd ..3 javah nativeTest.HelloNative ⽣成的nativeTest_HelloNative.h如下:1/* DO NOT EDIT THIS FILE - it is machine generated */2 #include <jni.h>3/* Header for class nativeTest_HelloNative */45 #ifndef _Included_nativeTest_HelloNative6#define _Included_nativeTest_HelloNative7 #ifdef __cplusplus8extern"C" {9#endif10/*11 * Class: nativeTest_HelloNative12 * Method: greeting13 * Signature: ()V14*/15 JNIEXPORT void JNICALL Java_nativeTest_HelloNative_greeting16 (JNIEnv *, jclass);1718 #ifdef __cplusplus19 }20#endif21#endifnativeTest_HelloNative.h 这个⽂件是在nativeTest⽂件夹外⽣成的,需要拖到nativeTest⽂件夹⾥⾯。
java调用c++程序实例
java调用c++程序实例在Java中调用C++程序,通常需要使用Java的本地方法接口(Java Native Interface,JNI)。
JNI允许Java代码和其他语言编写的代码进行交互,特别是C和C++。
下面是一个简单的示例,说明如何使用JNI 在Java中调用C++代码。
首先,创建一个Java类,其中包含一个本地方法声明:javapublic class HelloWorld {public native void sayHello();static {System.loadLibrary("HelloWorldImpl");}public static void main(String[]args) {new HelloWorld().sayHello();}}在上面的代码中,sayHello 方法是一个本地方法,它通过JNI调用C++代码。
我们使用System.loadLibrary 方法加载包含本地方法实现的库。
在这个例子中,库的名字是"HelloWorldImpl"。
接下来,我们需要使用javac 命令编译Java代码,并使用javah 命令生成C++头文件:bashjavacHelloWorld.javajavah -jniHelloWorld这将生成一个名为 HelloWorld.h 的C++头文件,其中包含本地方法的C++签名。
现在,我们可以编写C++代码来实现本地方法。
假设我们将C++代码保存在名为 HelloWorldImpl.cpp 的文件中:cpp#include <jni.h>#include "HelloWorld.h"#include <iostream>JNIEXPORT void JNICALL Java_HelloWorld_sayHello(JNIEnv *env, jobject obj) {std::cout << "Hello, World from C++!" << std::endl;}注意,在C++代码中,我们使用JNIEXPORT 和 JNICALL 宏来指定函数的返回类型和调用约定。
java中调用C#
我知道的有两种方法,一种是直接用JNI,另一种是则是用Jacob(实质上也用的是JNI)先讲讲第一种方法1.编写java程序TestDll,注意,这个类有两个作用,一个是用来做头文件,另外一个作用就是通过它来调用dllpublic class TestDll {static{System.loadLibrary("DLLSample");//载入dll}public native static int DoubleValue(int i);//函数声明}2.编译: javac TestDll3.生成头文件: javah TestDll生成TestDll.h文件,这里面只对函数DoubleValue作了声明/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h></jni.h>/* Header for class TestDll */#ifndef _Included_TestDll#define _Included_TestDll#ifdef __cplusplusextern "C" {#endif/** Class: TestDll* Method: DoubleValue* Signature: (I)I*/JNIEXPORT jint JNICALL Java_TestDll_DoubleValue(JNIEnv *, jclass, jint);#ifdef __cplusplus}#endif#endif4.用vc制作DLL修改DLLSample工程,程序中添加函数DoubleValue的实现,函数名必须用jni 规定格式,可以照到.h文件里的声明来写:#include "jni_md.h"#include "TestDll.h"JNIEXPORT jint JNICALL Java_TestDll_DoubleValue (JNIEnv *, jclass, jint p){int j = p*2;return j;}JNIEXPORT,JNICALL,JNIEnv *, jclass请都不要动,jint对应是java里的int别忘了把TestDll.h,jni.h(这个文件在jdk/include下),jni_md.h(这个文件在jdk/include/win32下)复制到VC工程目录中,然后编译生成dll5.把生成的DLLSample.dll复制到jdk/bin下(确保PATH指向了这个目录)6.应用我看到他们举的例子都是把调用写在了main里, 在这里我把应用取出来放在一个servlet类中的测试的,同样可以得到正确结果,这里体现国TestDll的第二个作用,它是调用dll的一个纽带......TestDll td = new TestDll();System.out.println("result= "+td.DoubleValue(25));.....注意:如果更改了TestDll的内容或重使命名了这个文件,必须重新用它生成头文件,在dll里也要做相应修改,因为必须要和java里面的声明一致才行。
