美文网首页
中间件技术——实验三: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