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方法实例详解的全部叙述,希望对大家有所帮助,如果大家想了解更多内容敬请关注小牛知识库网站!
本文向大家介绍JavaScript 中调用 Kotlin 方法实例详解,包括了JavaScript 中调用 Kotlin 方法实例详解的使用技巧和注意事项,需要的朋友参考一下 JavaScript 中调用 Kotlin 方法实例详解 Kotlin 编译器生成正常的 JavaScript 类,可以在 JavaScript 代码中自由地使用的函数和属性 。不过,你应该记住一些微妙的事情。 用独立的 J
本文向大家介绍Python 调用Java实例详解,包括了Python 调用Java实例详解的使用技巧和注意事项,需要的朋友参考一下 Python 调用Java实例详解 前言: Python 对服务器端编程不如Java 所以这方面可能要调用Java代码 前提: Linux 环境 1 安装 jpype1 安装后测试代码: 2 调用非jdk的jar包, test.jar 包中含有 com.Test类
我创建了一个类,该类旨在获取2个分数,每个分数都有一个分子和分母,然后将它们相加,输出另一个分数。 当我编译程序时,我遇到了一个问题,涉及: 分数F3=新分数。添加(F1、F2);在主要方法中 错误:找不到类型分数$add 如果我将所有内容都设置为一个类,那么程序将运行,但我希望所有方法都严格位于Fraction类中,并在UseFraction类中调用Fraction。
本文向大家介绍C#的FileSystemWatcher用法实例详解,包括了C#的FileSystemWatcher用法实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例详述了C#的FileSystemWatcher用法。分享给大家供大家参考。具体用法如下: FileSystemWatcher控件主要功能: 监控指定文件或目录的文件的创建、删除、改动、重命名等活动。可以动态地定义需要监控的文
本文向大家介绍Kotlin 语言中调用 JavaScript 方法实例详解,包括了Kotlin 语言中调用 JavaScript 方法实例详解的使用技巧和注意事项,需要的朋友参考一下 Kotlin 语言中调用 JavaScript 方法实例详解 Kotlin 已被设计为能够与 Java 平台轻松互操作。它将 Java 类视为 Kotlin 类,并且 Java 也将 Kotlin 类视为 Java
我正在使用Saxon(如果需要,我可以使用Xalan)XSLT处理器进行一些转换。我想将下面对象的实例作为参数传递给XSLT模板。 所以我创建了这个对象。 在XSLT文件中,我将参数声明为: 现在我的问题是如何在XSLT内调用该对象的任何实例方法(即.getValue())?有可能吗?我知道我可以调用不同Java类的静态方法,但这并不完全是我想要的。 此外,是否可以在XSLT中填充Java对象,即
本文向大家介绍java ThreadPoolExecutor 并发调用实例详解,包括了java ThreadPoolExecutor 并发调用实例详解的使用技巧和注意事项,需要的朋友参考一下 java ThreadPoolExecutor 并发调用实例详解 概述 通常为了提供任务的处理速度,会使用一些并发模型,ThreadPoolExecutor中的invokeAll便是一种。 代码 可以把需要执
本文向大家介绍Java中Arrays.asList()方法详解及实例,包括了Java中Arrays.asList()方法详解及实例的使用技巧和注意事项,需要的朋友参考一下 Arrays.asList() 是将数组作为列表。 问题来源于: 期望的输出是 list 里面也有4个元素,也就是 size 为4,然而结果是1。 原因如下: 在 Arrays.asList 中,该方法接受一个变长参数,一般可看