Java调用C# DLL
由于项目需要,利用了短信猫,但是一个短信猫会加载多个串口,而只需要其AT口,通过java代码,获取其AT口对应的串口号比较困难,于是通过C#获取,这里直接调用C#生成的DLL,但java不能直接调用C#生成的DLL,需要用C++作为桥接,这里介绍一种方法调用C#所生成的DLL文件。
开发环境为:Myeclipse10.0
VS2010
1.首先创建一个Java文件,命名为TestJNI,代码如下:
package msg;
public class TestJNI {
public native string GetATComNumber();
static {
System.loadLibrary("CPP");
}
public static void main(String[] args) {
TestJNI t = new TestJNI();
String data=t.GetATComNumber();
for(string s:data)
System.out.println(s);
}
}
然后利用javac对该java文件进行编译,然后利用javah命令生成对应的.h文件,注意这里的路径很重要,直接在工程的src路径下,利用包名对java文件进行编译,利用javah文件也是如此。这里会生成一个对应的h文件,留着备用
2.写相应的C#代码,创建一个C#类库,代码如下:
namespace GetAtComNumberArrays
{
public class ATCOMS
{
public ATCOMS()
{
data = MulGetHardwareInfo(HardwareEnum.Win32_PnPEntity, "Name");
}
public string data;
/// <summary>
/// 枚举win32 api
/// </summary>
public enum HardwareEnum
{
Win32_PnPEntity, // 所有设备
}
public string MulGetHardwareInfo(HardwareEnum hardType, string propkey)
{
List<string> strs = new List<string>();
StringBuilder data = new StringBuilder();
try
{
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("select *from " + hardType))
{
var hardInfos = searcher.Get();
foreach (var hardInfo in hardInfos)
{
if (hardInfo.Properties[propkey].Value.ToString().Contains("COM"))
{
strs.Add(hardInfo.Properties[propkey].Value.ToString());
}
}
searcher.Dispose();
}
string[] datatemps = strs.ToArray();
foreach (string datastring in datatemps)
{
if (datastring.Contains("AT"))
{
int index = datastring.IndexOf('(');
);
)
temp = temp.Substring(, ) + "*";
else
temp = temp.Substring(, ) + "*";
data.Append(temp);
}
}
return data.ToString();
}
catch
{
return null;
}
finally
{
data = null;
}
}
}
}
然后生成对应的DLL文件
3.创建一个C++DLL(新建->Win32项目->DLL) 然后将在1和2步骤中生成的.h文件和DLL文件考入项目中(和.cpp一个目录),代码如下:
#include "stdafx.h"
#include "jni.h"
#include "jni_md.h"
#include "com_raycom_tools_SerialPortTools.h"
#include "string.h"
#include <malloc.h>
#include <stdlib.h>
#include <vcclr.h>
#using "GetAtComNumberArrays.dll"
using namespace GetAtComNumberArrays;
#using "mscorlib.dll"
#using "System.dll"
#using "System.Web.dll"
#using "System.Web.Services.dll"
#using "MessageCenter.dll"
using namespace System;
using namespace System::Text;
using namespace System::Web;
using namespace System::Web::Services;
using namespace System::ComponentModel;
using namespace MessageCenter;
// char* To jstring
jstring stringTojstring(JNIEnv* env, const char* pat)
{
jclass strClass = env->FindClass("Ljava/lang/String;");
jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(pat));
env->SetByteArrayRegion(bytes, , strlen(pat), (jbyte*)pat);
jstring encoding = env->NewStringUTF("utf-8");
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
}
// String To jstring
jstring strTojstring(JNIEnv* env, String^ rtn)
{
pin_ptr<const wchar_t> wch = PtrToStringChars(rtn);
size_t convertedChars = ;
size_t sizeInBytes = ((rtn->Length + ) * );
char *ch = (char *)malloc(sizeInBytes);
errno_t err = wcstombs_s(&convertedChars,
ch, sizeInBytes,
wch, sizeInBytes);
jstring js = stringTojstring(env, ch);
free(ch);
return js;
}
JNIEXPORT jstring JNICALL Java_com_raycom_tools_SerialPortTools_getATComNumber
(JNIEnv *env, jobject)
{
ATCOMS ^temp=gcnew ATCOMS();
return strTojstring(env,temp->data);
}
由于这里要返回值为String,所以要进行相应的转换,转换函数已经给出,出处为:http://7wolfs.iteye.com/blog/2043835
编译的时候需要jni.h和jni_md.h,在jdk下搜索,找出这两个文件,在VS的安装目录下找出MessageCenter.dll,Interop.RTXSAPILib.dll,将其拷入C++文件中(目录为.CPP相同目录)
编译时将.h文件中的 #include <jni.h>改成#include "jni.h"
这里还要将C++的属性进行修改:选择《项目》-> 《属性页》->《配置属性》->《常规》->《公共语言运行库支持》,选择公共语言运行库支持(/clr)
然后生成DLL.
4.将生成的C++DLL文件和C#生成的DLL文件都拷入myeclipse自带JDK的bin目录下,注意是myeclipse自带JDK的bin目录下,我的目录为:C:\Users\more\AppData\Local\MyEclipse Professional 2014\binary\com.sun.java.jdk7.win32.x86_1.7.0.u45\bin
然后运行TestJNI得到结果。
如有问题,请留言。
Java调用C# DLL的更多相关文章
- Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()
Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...
- paip.java 调用c++ dll so总结
paip.java 调用c++ dll so总结 ///////JNA (这个ms sun 的) 我目前正做着一个相关的项目,说白了JNA就是JNI的替代品,以前用JNI需要编译一层中间库,现在JNA ...
- 巧用C#做中间语言 实现Java调用.net DLL
本文将详细为大家介绍一个java调用.net DLL的方法,以实现特殊的客户的特殊要求:“在Java项目中必须使用其提供的用.net写的DLL加密机制!” 环境与工具: ◆.net framework ...
- [JNI] Java 调用 C++ dll
首先介绍一下JNI吧! JNI 是Java提供的一个用于调用本地接口的接口层,位于Java代码 和 本地代码之间的一层:主要功能是 数据类型的转换,还有就是通过这一层来调用本地代码! 下面就说说Jav ...
- java调用C++ DLL库方法
最近一个项目要开发网页端人脸识别项目,人脸识别的算法已经写好,是C++版,但是网页端要求使用Java后台,这就涉及到Java调用DLL的问题.经过查找,实现了一个简单的例子. 1.第一步,先在Java ...
- java调用c#dll文件配置
1 在强大的c#语言和java语言之间,二者难免会因为某些特殊的要求会相互调用. 下面就以java调用c#的dll为例做详细介绍 1 在vs中的环境设置如下图,图片中程序仅作为讲解程序,在项目编译成 ...
- java调用c++ dll出现中文乱码
近期的开发用到了使用java调用本机动态连接库的功能,将文件路径通过java调用C++代码对文件进行操作. 在调用中假设路径中包括有中文字符就会出现故障.程序执行就会中止. 以下用一个小样例,来说明记 ...
- JAVA调用动态链接库(dll)
菜鸡爬坑 基础知识 因为某个东西的keygen我只会在win下生成!! 所以只能出此下策!!之前一直是android下用jni调用so文件,现在试下java在win平台下调用dll 首先还是 ...
- JAVA调用动态链接库DLL之JNative学习
package com.ehfscliax; import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import ...
随机推荐
- swift之函数式编程(四)
文章内容来自<Functional Programing in Swift>,具体内容请到书中查阅 Map, Filter, Reduce Functions that take func ...
- AngularJS学习篇(二十)
AngularJS 包含 在 AngularJS 中,你可以在 HTML 中包含 HTML 文件. 使用 AngularJS, 你可以使用 ng-include 指令来包含 HTML 内容: < ...
- Webpack 入门教程
Webpack 是一个前端资源加载/打包工具.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 本章节基于 Webpack3.0 测试通过. 从图中我们可以看出,W ...
- kafka学习笔记2:生产者
这次的笔记主要记录一下kafka的生产者的使用和一些重要的参数. 文中主要截图均来自kafka权威指南 主要涉及到两个类KafkaProducer和ProducerRecord. 总览 生产者的主要架 ...
- 使用python3的typing模块提高代码健壮性
前言:很多人在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数,返回什么类型的结果,就不得不去阅读代码的具体内容,降低了阅读的速度,加上Python本身就是一门弱类型的语言,这种 ...
- Java并发Fork-Join框架原理解析
1.什么是Foirk/Join框架 Fork/Join框架是Java7提供用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 2.什么是并行流与顺 ...
- Windows Forms DataGridView中合并单元格
Windows Forms DataGridView 没有提供合并单元格的功能,要实现合并单元格的功能就要在CellPainting事件中使用Graphics.DrawLine和 Graphics.D ...
- 插件lombok的介绍安装
Lombok插件 介绍一个不错的Eclipse插件Lombok 该插件对Log4j简化的代码,因为不大,所以jar包也存在呢! Lombox是Eclipse的一个插件,用来自动生成Java代码,减少手 ...
- HDnoip2017题解
那么,作为一名初入信息竞赛的选手,我也试着开始用博客记录自己的学习历程,那么这篇文章先简单介绍一下我自己吧. 本人开始学习信息学大概以来,主要都是用的C++,所以对其他语言并不是十分熟悉.2016我还 ...
- RabbitMQ之工作队列
工作队列 工作队列(又称:任务队列Task Queues)是为了避免等待一些占用大量资源.时间的操作,当我们把任务Task当做消息发送队列中,一个运行在后台的工作者worker进程就会取出任务然后处理 ...