C#调用Java方法(详细实例)

C#可以直接引用C++的DLL和转换JAVA写好的程序。最近由于工作原因接触这方面比较多,根据实际需求,我们通过一个具体例子把一个JAVA方法转换成可以由C#直接调用的DLL

C#调用c++

C#调用C++的例子网上很多,以一个C++的具体方法为例。

C++代码

// 获取一帧图像数据
MVSMARTCAMCTRL_API int __stdcall MV_SC_GetOneFrame(IN void* handle,
IN OUT unsigned char *pData ,
IN unsigned int nDataSize,
IN OUT MV_SC_IMAGE_OUT_INFO* pstImageInfo);
// 结果数据缓存的上限
#define MV_SC_MAX_RESULT_SIZE (1024*16) // 输出帧的信息
typedef struct _MV_SC_IMAGE_OUT_INFO_
{
unsigned short nWidth; // 图像宽
unsigned short nHeight; // 图像高
unsigned int nFrameNum; // 帧号
unsigned int nFrameLen; // 当前帧数据大小
unsigned int nTimeStampHigh; // 时间戳高32位
unsigned int nTimeStampLow; // 时间戳低32位
unsigned int nResultType; // 输出的消息类型
// 根据消息类型对应不同的结构体
unsigned char chResult[MV_SC_MAX_RESULT_SIZE];
unsigned int nReserved[8]; // 保留
}MV_SC_IMAGE_OUT_INFO

C#代码

    /// <summary>
/// 获得相机所拍照片
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
[DllImport("MvSmartCamCtrl.dll")]
public static extern int MV_SC_GetOneFrame(IntPtr handle, Byte[] pData, int nDataSize, out MV_SC_IMAGE_OUT_INFO pstDevInfo); // 输出帧的信息
[StructLayout(LayoutKind.Sequential)]
public struct MV_SC_IMAGE_OUT_INFO
{
public short nWidth; // 图像宽
public short nHeight; // 图像高
public int nFrameNum; // 帧号
public int nFrameLen; // 当前帧数据大小
public int nTimeStampHigh; // 时间戳高32位
public int nTimeStampLow; // 时间戳低32位
public int nResultType; // 输出的消息类型
// 根据消息类型对应不同的结构体
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024 * 16)]
public MV_SC_RESULT_BCR chResult;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public int[] nReserved;
}

这样我们把这个DLL放在程序根目录下,就能实现DLL方法的调用。

C#调用JAVA方法

IKVM.NET是一个针对Mono和微软.net框架的java实现,其设计目的是在.NET平台上运行java程序。它包含了以下的组件:用.NET实现的java虚拟机,java类库的.NET实现。
致力于在java和.NET之间交互的工具。

程序需求

我们有一个JAVA写好的Demo,传的参数是用Gzip进行压缩传到服务器的,代码如下:


package Demo; import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import com.google.gson.Gson; public class Demo
{ public static String doPostClient(String json, String url)
{
HttpClient httpClient = new HttpClient();
String rval = "";
PostMethod postMethod = new PostMethod(url);
try
{
Gson gson = new Gson();
InputStream in = new ByteArrayInputStream(objectToByte(json));
postMethod.setRequestBody(in);
HttpClientParams params = new HttpClientParams();
httpClient.setParams(params);
httpClient.executeMethod(postMethod);
byte[] b = postMethod.getResponseBody();
String rtnData = (String) byteToObject(b);
rval = gson.toJson(rtnData);
} catch (Exception e)
{
rval="erro:"+e.getMessage();
} finally
{
postMethod.releaseConnection();
}
return rval;
} public static byte[] objectToByte(java.lang.Object obj)
{
byte[] bytes = null;
ObjectOutputStream oo = null;
try
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(obj.toString().getBytes("utf-8"));
gzip.close();
bytes = out.toByteArray(); } catch (Exception e)
{
e.printStackTrace();
} finally
{
if (oo != null)
{
try
{
oo.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
return bytes;
} private static java.lang.Object byteToObject(byte[] bytes)
{
String obj = "";
ObjectInputStream oi = null;
try
{
ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
GZIPInputStream gzipi = new GZIPInputStream(bi);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(gzipi, "UTF-8"));
String line;
while ((line = bufferedReader.readLine()) != null)
{
obj+=line;
}
} catch (Exception e)
{
e.printStackTrace();
} finally
{
if (oi != null)
{
try
{
oi.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
return obj;
} }

这个代码我用C#改写了,用HttpWebRequest的方式传到服务器,服务器那边Gzip解压不了,查了原因是因为Java与C#的Byte类型值范围不同,我们有两种解决思路,一种是将这个JAVA做成webservice挂在服务器上,c#再去调用,第二种就是将这个方法编译成可由C#直接调用的DLL,由于这个方法功能比较单一,我们选取了后者。

环境配置

IKVM.NET 下载后解压得到BIN文件夹中的数据,用于JAR包转换和基础DLL。
IKVM.OpenJDK.ClassLibrary.dll用于C#程序接入。
下载地址:https://yunpan.cn/cBHTS5fXsIe9v 访问密码 0847。
将IKVM.NET的BIN文件夹的地址添加到环境变量。
计算机右键属性--高级系统设置--高级--环境变量--在系统变量中找到PATH--将BIN文件夹的地址添加进去,
在CMD中输入ikvmc 有帮助文档说明环境配置成功。
Bin文件夹下的IKVM.OpenJDK.Core.dll,IKVM.Runtime.dll,IKVM.Runtime.JNI.dll和IKVM.OpenJDK.ClassLibrary.dll为公共DLL,所有转换程序都需引用

转换步骤

1.确定引用关系:
该Demo的结构如下:

Demo.jar 依赖于 commons-httpclient-3.1.jar 和 gson-2.4.jar
commons-httpclient-3.1.jar 依赖于 commons-logging-1.1.3.jar 和 commons-codec-1.6.jar

我们先将gson-2.4.jar,commons-logging-1.1.3.jar,commons-codec-1.6.jar 生成DLL,语法如下:

ikvmc JAR包物理路径。
win7系统默认生成在C:\Users\Administrator 这个文件夹下

commons-httpclient-3.1.dll 生成语法如下:

ikvmc commons-httpclient-3.1.jar -r:commons-logging-1.1.3.dll -r:commons-codec-1.6.dll

我们将Demo打包的名字为JavaApi.Demo 这样生成的 JavaApi.dll 生成语法如下:

ikvmc JavaApi.Demo.jar -r:commons-httpclient-3.1.dll -r:gson-2.4.dll

上面的文件都是相对应的物理路径,然后将所有生成的DLL添加到C#项目中引用,包括之前的公共DLL,引用到项目中所有引用的DLL如图:

这样就可以直接在程序中使用这个java方法了
Demo.Demo.doPostClient(js, url);
第一个Demo java程序中的package名。
第二个Demo java程序中的class名。

C#调用Java方法的更多相关文章

  1. C++调用JAVA方法详解

    C++调用JAVA方法详解          博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...

  2. C#调用Java方法(详细实例)

    C#可以直接引用C++的DLL和转换JAVA写好的程序.最近由于工作原因接触这方面比较多,根据实际需求,我们通过一个具体例子把一个JAVA方法转换成可以由C#直接调用的DLL C#调用c++ C#调用 ...

  3. Js调用Java方法并互相传参

    Js通过PhoneGap调用Java方法并互相传参的. 一.JAVA代码 写一个类,该类继承自Plugin并重写execute方法. import org.json.JSONArray; import ...

  4. HAL中通过JNI调用java方法【转】

    转载请注明本文出处:http://www.cnblogs.com/xl19862005 作者:Xandy 由于工作的需要,最近一直在研究HAL.JNI.Java方法之间互调的问题,并做了如下一些记录和 ...

  5. cocos2d-x中使用JNI的调用JAVA方法

    用cocos2d-x公布Android项目时.都应该知道要用JAVA与C/C++进行交互时会涉及到JNI的操作(Java Native Interface).JNI是JAVA的一个通用接口.旨在本地化 ...

  6. Android Studio NDK开发-JNI调用Java方法

    相对于NDK来说SDK里面有更多API可以调用,有时候我们在做NDK开发的时候,需要在JNI直接Java中的方法和变量,比如callback,系统信息等.... 如何在JNI中调用Java方法呢?就需 ...

  7. java native interface JNI 调用Java方法

    在上一篇文章中介绍了JNI.以及java调用JNI.这篇讲一下 JNI调用java方法. 通过使用合适的JNI函数,你能够创建Java对象,get.set 静态(static)和 实例(instanc ...

  8. Qt 调用 Java 方法笔记

    Qt 调用 Java 方法笔记 假设遇到相似的错误: error: undefined reference to '_jstring* QAndroidJniObject::callStaticMet ...

  9. 第5篇-调用Java方法后弹出栈帧及处理返回结果

    在前一篇 第4篇-JVM终于开始调用Java主类的main()方法啦 介绍了通过callq调用entry point,不过我们并没有看完generate_call_stub()函数的实现.接下来在ge ...

随机推荐

  1. 第七届河南省赛A.物资调度(dfs)

    10401: A.物资调度 Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 95  Solved: 54 [Submit][Status][Web Bo ...

  2. Android开发(26)--补间动画(Tween)的实现

    补间动画(Tween Animation) 补间动画与逐帧动画在本质上是不同的,逐帧动画通过连续播放图片来模拟动画的效果,而补间动画则是通过在两个关键帧之间补充渐变的动画效果来实现的.补间动画的优点是 ...

  3. 《网络编程》Unix 域套接字

    概述 Unix 域套接字是一种client和server在单主机上的 IPC 方法.Unix 域套接字不运行协议处理,不须要加入或删除网络报头,无需验证和,不产生顺序号,无需发送确认报文,比因特网域套 ...

  4. #ifdef _cplusplus

    时常在cpp的代码之中看到这样的代码: #ifdef __cplusplus extern "C" { #endif //一段代码 #ifdef __cplusplus } #en ...

  5. web 开发规范

    好久没整理博文了 啰嗦两句  转载至新浪...... 于在未开启cleartype的情况下,一些中文字体在非偶数字号下的显示效果欠佳,所以一般建议使用12.14.16.18.22px等偶数字号.也就 ...

  6. DevExpress ASP.NET 使用经验谈(1)-XPO模型的创建

    这个系列通过一些简单例子循序渐进,介绍DevExpress ASP.NET控件的使用.先来介绍一下XPO的使用,安装的DevExpress版本为DXperienceUniversal-12.2.4,使 ...

  7. [Jobdu] 题目1521:二叉树的镜像

    不知道怎么回事下面的代码通过了4个测试用例,还有1个测试用例始终是Runtime Error,各位帮我看一下是哪里出了问题 镜像输出两种方法,一种是递归进行调整,另外一种就是直接在先序遍历的基础上进行 ...

  8. HDU 2087 剪花布条(模式串在主串中出现的次数主串中子串不可重叠)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 题意:求模式串在主串中出现的次数,与模式串匹配的子串之间不可重叠. 思路:用kmp算法解决,在匹 ...

  9. BZOJ 2561: 最小生成树(最小割)

    U,V能在最小(大)生成树上,当且仅当权值比它小(大)的边无法连通U,V. 两次最小割就OK了. --------------------------------------------------- ...

  10. Hadoop学习笔记(2)hadoop框架解析

    Hadoop是适合大数据的分布式存储与计算平台 HDFS的架构:主从式结构 主节点只有一个NameNode,从节点可以有很多个DataNode. NameNode负责: (1)接收用户操作请求 (2) ...