由于项目需要,利用了短信猫,但是一个短信猫会加载多个串口,而只需要其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的更多相关文章

  1. Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()

    Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...

  2. paip.java 调用c++ dll so总结

    paip.java 调用c++ dll so总结 ///////JNA (这个ms sun 的) 我目前正做着一个相关的项目,说白了JNA就是JNI的替代品,以前用JNI需要编译一层中间库,现在JNA ...

  3. 巧用C#做中间语言 实现Java调用.net DLL

    本文将详细为大家介绍一个java调用.net DLL的方法,以实现特殊的客户的特殊要求:“在Java项目中必须使用其提供的用.net写的DLL加密机制!” 环境与工具: ◆.net framework ...

  4. [JNI] Java 调用 C++ dll

    首先介绍一下JNI吧! JNI 是Java提供的一个用于调用本地接口的接口层,位于Java代码 和 本地代码之间的一层:主要功能是 数据类型的转换,还有就是通过这一层来调用本地代码! 下面就说说Jav ...

  5. java调用C++ DLL库方法

    最近一个项目要开发网页端人脸识别项目,人脸识别的算法已经写好,是C++版,但是网页端要求使用Java后台,这就涉及到Java调用DLL的问题.经过查找,实现了一个简单的例子. 1.第一步,先在Java ...

  6. java调用c#dll文件配置

    1 在强大的c#语言和java语言之间,二者难免会因为某些特殊的要求会相互调用. 下面就以java调用c#的dll为例做详细介绍 1  在vs中的环境设置如下图,图片中程序仅作为讲解程序,在项目编译成 ...

  7. java调用c++ dll出现中文乱码

    近期的开发用到了使用java调用本机动态连接库的功能,将文件路径通过java调用C++代码对文件进行操作. 在调用中假设路径中包括有中文字符就会出现故障.程序执行就会中止. 以下用一个小样例,来说明记 ...

  8. JAVA调用动态链接库(dll)

        菜鸡爬坑 基础知识  因为某个东西的keygen我只会在win下生成!! 所以只能出此下策!!之前一直是android下用jni调用so文件,现在试下java在win平台下调用dll 首先还是 ...

  9. JAVA调用动态链接库DLL之JNative学习

    package com.ehfscliax; import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import ...

随机推荐

  1. Leetcode题解(31)

    103. Binary Tree Zigzag Level Order Traversal 题目 分析: 广度优先遍历的应用.重点是掌握vector的reverse函数,一开始我忘记有这个函数了,琢磨 ...

  2. 利用VS2008发布一个简单的webservice

    一个开发好的webservice,怎样发布出去,供其他电脑访问呢? 本文将介绍如何发布一个简单的webservice,其中的内容都是在网上查看别人文章,自己仿照着做了一遍,因此,难免会发生错误,如果发 ...

  3. CodeForces - 556A Case of the Zeros and Ones

    //////////////////////////////////////////////////////////////////////////////////////////////////// ...

  4. Peaceful Commission

    Peaceful Commission Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...

  5. (二): 基于ZeroMQ的实时通讯平台

    基于ZeroMQ的实时通讯平台 上篇:C++分布式实时应用框架 (Cpp Distributed Real-time Application Framework)----(一):整体介绍 通讯平台作为 ...

  6. SSL证书简介

    前言 之前写了一篇本站点如何部署SSL证书的文章<Centos7.4下用Docker-Compose部署WordPress(续)-服务器端用Nginx作为反向代理并添加SSL证书(阿里云免费DV ...

  7. JQ图片文件上传之前预览功能

    1.先准备一个div onchange触发事件 <input  type="file" onchange="preview(this)" >< ...

  8. C#图片水印代码整理

    这一段公司有个项目,客户要求上传的图片要带上自定义的水印.以前也经常和朋友讨论C#图片水印方面的问题,但是从来没有实际操作过.所以,借这次项目的机会也研究了一下C#图片水印的功能!本人参考的是disc ...

  9. C#编程命名规范推荐

    1.用Pascal规则来命名方法和类型. Pascal 大小写形式是指名称中的单词的第一个字母大写public class DataGrid{public void DataBind(){ }} 2. ...

  10. [转载] Netty教程

    转载自http://blog.csdn.net/kobejayandy/article/details/11493717 先啰嗦两句,如果你还不知道Netty是做什么的能做什么.那可以先简单的搜索了解 ...