美文网首页
中间件技术——实验三:COM组件和调用

中间件技术——实验三:COM组件和调用

作者: 东郭_先森 | 来源:发表于2019-04-17 21:17 被阅读0次

    一、实验内容

    1. 实验准备操作
      a.下载安装java jdk 1.6或以上(笔者用的版本是1.8.0_201);
      b.安装vs studio ;http://mocom.xmu.edu.cn/home/project/soft/Visual%20Studio/vs_community__2017.exe
      c.熟悉IDEA或eclipse等开发环境(笔者用的版本是IDEA 2018.3.5)。
      d.windows10家庭版
    2. 实验内容
      a.构建一个com组件,该组件可以对一个字符串数组进行压缩和解压缩(压缩和解压算法自己定义,或者调用其他的库);

    二、实验过程

    (绝大部分过程需要使用管理员权限打开,因为涉及到写入注册表等操作)
    1.构建com组件
    使用管理员权限打开安装好的VS2017(右键->以管理员权限打开),在VISUAL C#下新建一个类库(.NET FRAMEWORK)名称命名为ComToJava,如下图:


    新建一个类库

    双击解决方案中的Properties,修改项目的配置。按图中所示操作






    此时解决方案会出现这个



    image.png
    将以下代码拷贝到ComToJava.cs
    using System;
    using System.IO;
    using System.IO.Compression;
    using System.Runtime.InteropServices;
    using System.Text;
    
    namespace ComToJava
    
    {
        [Guid("FC517C46-34F9-4ED5-BF5A-C977501272E7")]
        public interface IMyClass
        {
            byte[] Compress(byte[] data);
            byte[] Decompress(byte[] data);
            string CompressString(string str);
            string DecompressString(string str);
        }
    
        [ClassInterface(ClassInterfaceType.None)]
        [Guid("A5C4EB67-83DE-4B98-A413-5BEFD01F0774")]
        [ProgId("ComToJava.Application")]
        public class ComToJava : IMyClass
        {
            public byte[] Compress(byte[] data)
            {
                try
                {
                    MemoryStream ms = new MemoryStream();
                    GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true);
                    zip.Write(data, 0, data.Length);
                    zip.Close();
                    byte[] buffer = new byte[ms.Length];
                    ms.Position = 0;
                    ms.Read(buffer, 0, buffer.Length);
                    ms.Close();
                    return buffer;
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }
            }
            public byte[] Decompress(byte[] data)
            {
                try
                {
                    MemoryStream ms = new MemoryStream(data);
                    GZipStream zip = new GZipStream(ms, CompressionMode.Decompress, true);
                    MemoryStream msreader = new MemoryStream();
                    byte[] buffer = new byte[0x1000];
                    while (true)
                    {
                        int reader = zip.Read(buffer, 0, buffer.Length);
                        if (reader <= 0)
                        {
                            break;
                        }
                        msreader.Write(buffer, 0, reader);
                    }
                    zip.Close();
                    ms.Close();
                    msreader.Position = 0;
                    buffer = msreader.ToArray();
                    msreader.Close();
                    return buffer;
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }
            }
            public string CompressString(string str)
            {
                string compressString = "";
                byte[] compressBeforeByte = Encoding.UTF8.GetBytes(str);
                byte[] compressAfterByte = Compress(compressBeforeByte);
                //compressString = Encoding.GetEncoding("UTF-8").GetString(compressAfterByte);    
                compressString = Convert.ToBase64String(compressAfterByte);
                return compressString;
            }
            public string DecompressString(string str)
            {
                string compressString = "";
                //byte[] compressBeforeByte = Encoding.GetEncoding("UTF-8").GetBytes(str);    
                byte[] compressBeforeByte = Convert.FromBase64String(str);
                byte[] compressAfterByte = Decompress(compressBeforeByte);
                compressString = Encoding.UTF8.GetString(compressAfterByte);
                return compressString;
            }
        }
    }
    

    进入新建GUID界面,选择第5个选项,之后单击“新建GUID”,再单击“复制”,再到代码中粘贴GUID,详细见下图:



    创建两个GUID到图中的地方覆盖掉



    然后生成解决方案就大功告成了

    如果说刚开始打开vs2017的时候没有使用管理员权限,在生成解决方案的时候就会报错,大概意思是权限不够,拒绝访问,我这边已经是生成过了,如果要重新生成解决方案,权限不够的话也会报错,如下图:

    这个时候查看项目路径的bin\debug,会发现多了一个ComToJava,dll文件



    然后我们要注册该文件,需要使用两个命令
    gacutil /i ComToJava.dll 
    regasm ComToJava.dll 
    

    使用管理员权限打开开始界面中vs 2017目录下的“开发人员命令提示符”



    如果没有使用管理员权限就会出现如下错误:



    使用管理员权限就可以成功添加进缓存

    然后我们注册该dll文件



    发现图中的问题,原因是版本不匹配, 如果要正常注册dll,regasm必须能够支持dll对应的Framework的版本,这个时候我们需要调用4.0版本的regasm来注册,使用管理员权限打开cmd命令提示符(右键开始->选择“命令提示符(管理员)”),不是使用管理员权限的话又会出现权限不足的错误,输入的语句是
    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe D:\缓存VS\ComToJava\ComToJava\bin\Debug\ComToJava.dll
    

    前半部分是REGASM的路径,后半部分是dll文件的路径
    结果如下图:



    COM组件的创建和注册到这里就结束了
    2.使用java调用COM组件
    打开IDEA,新建一个project,main函数的代码为(缺少的包按ALT+ENTER导入5):

            ActiveXComponent axc = new ActiveXComponent("ComToJava.Application");//获取对象
            Dispatch dis = axc.getObject();
    
            String test = "test";
            System.out.println(test);
            Variant v1 = Dispatch.call(dis, "CompressString", test);
            System.out.println(v1);
    
            Variant v2 = Dispatch.call(dis, "DecompressString", v1);
            System.out.println(v2);
    

    运行结果为


    三、总结及一些细节

    1.COM全称The Component Object Model,组件对象模型,是一种基于COM的、已编译好的软件组件,可为应用程序、操作系统以及其他组件提供服务。COM不是一种语言,而是一种标准、规范,包括一套标准API,一个标准的接口集以及COM用于支持分布式计算的网络协议。在我实验过程中,我感觉COM组件就是一个工具,做好这个工具后,你可以拿着它到其他系统、其他ide中使用。
    2.GUID全称Globally Unique Identifier,全局唯一标识符。世界上的任何两台计算机都不会生成重复的 GUID 值。GUID 主要用于在拥有多个节点、多台计算机的网络或系统中,分配必须具有唯一性的标识符。在 Windows 平台上,GUID 应用非常广泛:注册表、类及接口标识、数据库、甚至自动生成的机器名、目录名等。
    3.Java使用COM组件时,连接的部分为




    4.字符串压缩的方法有很多种,本文选用的是GZIP,其他方法上网搜“C# 压缩字符串数组”
    5.输入的字符串数组为Byte[]型,返回的是SafeArray,没办法直接输出,于是将Byte[]类型转换为String型,可以较为简便的输入输出。

    相关文章

      网友评论

          本文标题:中间件技术——实验三:COM组件和调用

          本文链接:https://www.haomeiwen.com/subject/ssxniqtx.html