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方法(详细实例) 阅读目录 C#调用c++ C#调用JAVA方法 C#可以直接引用C++的DLL和转换JAVA写好的程序.最近由于工作原因接触这方面比较多,根据实际需求,我们通过一个具 ...

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

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

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

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

  4. java native interface JNI 调用Java方法

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

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

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

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

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

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

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

  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. C#版的eval,C#Light开源嵌入式脚本,unity热更新不再愁

    目前最新版本AlphaV0.06 完全的c#语法,可用于一切能运行C#的场合,wp windows xamarin mono asp.net unity3d 内嵌了int uint bool stri ...

  2. Field 'id' doesn't have a default value

    首先原因在于没有设置主键自增长. mysql的自增长模式是IDENTITY. jpa标签: @Id @GeneratedValue(strategy=GenerationType.IDENTITY) ...

  3. VS 2008 生成操作中各个选项的差别

    近日,在编译C#项目时经常发现有些时候明明代码没错,但就是编译不过,只有选择重新编译或者清理再编译才会不出错,本着求学的态度,搜罗了下VS2008IDE中生成操作的种类以及差别,整理如下:   内容( ...

  4. 鸟哥的Linux私房菜——基础学习篇 —— 笔记2

    at 语法 == 注意,输入at之后便进入命令行模式 ------- 不管怎么样,只会执行一次. [test @test test]# at [-m] TIME (输入工作指令)[test @test ...

  5. 说说设计模式~ 模版模式(Template)

    返回目录 模版模式,又被称为模版方法模式,它可以将工作流程进行封装,并且对外提供了个性化的控制,但主流程外界不能修改,也就是说,模版方法模式中,将工作的主体架构规定好,具体类可以根据自己的需要,各自去 ...

  6. js 优化

    一.for循环的优化 <!doctype html> <html lang="en"> <head> <meta charset=&quo ...

  7. Java override 和 overload 的区别

    override 是重写(覆盖)了一个方法,用来实现不同的功能,一般是用于子类继承父类时,重写父类的方法的时候. 重写(覆盖)的规则: 1.重写方法的参数列表必须表示与被重写的方法相同,否则不能称为重 ...

  8. v-show和v-if的区别

    v-show和v-if的区别

  9. XML学习笔记2——DTD

    在上一篇笔记中,将文档类型分类时,曾经根据文档是否使用并遵守了DTD或Schema来区分为格式良好的XML和有效的XML,那么什么是DTD和Schema呢?DTD和Schema都是用来规范XML文档的 ...

  10. javascript中数组的22种方法

    × 目录 [1]对象继承 [2]数组转换 [3]栈和队列[4]数组排序[5]数组拼接[6]创建数组[7]数组删改[8]数组位置[9]数组归并[10]数组迭代[11]总结 前面的话 数组总共有22种方法 ...