由于项目需要,利用了短信猫,但是一个短信猫会加载多个串口,而只需要其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. 读书笔记-你不知道的JS中-promise(2)

    继续填坑 模式 考虑下面的代码: function fn(x) { //do something return new Promise(function(resolve, reject) { //调用 ...

  2. 总结:PyQt5自定义信号源

    定义一个信号源有4个方面要注意: 1.定义信号源 A = pyqtSignal([str], [int,str]) 这里特别使用信号源重载的情况加以说明.如上就是信号源A的重载,一个可以发送str参数 ...

  3. jsoup从表单中取数据

    表单的格式如下 <td>user</td> <td>cc</td> </tr> <tr> <td>pass</ ...

  4. JavaScript 和 TypeScript 交叉口 —— 类型定义文件(*.d.ts)

    在 <从 JavaScript 到 TypeScript 系列> 文章我们已经学习了 TypeScript 相关的知识. TypeScript 的核心在于静态类型,我们在编写 TS 的时候 ...

  5. 按键(vb)启动指定目录的程序以及获取当前应用路径

    Private Declare Function GetDesktopWindow Lib "user32" () As Long Private Declare Function ...

  6. C#.Net调用VB.Net中的MY

    用过VB.NET的人应该只要MY有多强大了吧,是不是很想在C#中也能调用呢? 当然是可以的,.net作为微软的跨语言的平台,必须是能实现的,不然微软就自己打自己嘴巴了~ 回到正题上: 1.在程序中加上 ...

  7. c++ const全局对象是如何处理的

    我主要是记录一个发现,目前我不能解释,先作个记录. const 只是一个 语义约束,由编译器强制实施的.使被约束的对象不能被直接访问修改. 我用 『直接』这词,因为在代码段中 ,用一个const 指针 ...

  8. MyBatis学习笔记1--初识MyBatis

    我也是初学者,写博客只是想把自己的整个思路整理一下,有不对或者不好的地方,请大家多多指正. 1.MyBatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射. ...

  9. [转载] ZooKeeper的Java客户端API

    转载自 http://www.cnblogs.com/ggjucheng/p/3370359.html http://zookeeper.apache.org/doc/trunk/javaExampl ...

  10. pt-stalk

    1.名词解释 Collect forensic data about MySQL when problems occur 在问题发生的时候采集现场数据 pt-stalk waits for a tri ...