欢迎来到老马的领地~ 这是“压风式散热底座”发明者的个人网站:) 本人QQ:80524554,用户群1:562279766
折腾了一晚,中途看火影浪费了点时间happy.gif

说正事~~

并不复杂,但有些小细节需要注意,以下是流程:

一,用C#的类型库工程来生成DLL,并设置工程的属性为"COM可见":

http://www.m5home.com/blog//uploadfiles/8_79684.png


    另外,为了本机方便调试,可以把自动注册的选项勾上,相当于VB6里编译DLL时默认注册:

http://www.m5home.com/blog//uploadfiles/220j9del1d_49823.png


二,代码里面要编写一个接口,以及这个接口的实现类,并且接口与类都要设置为COM可见:

[ComVisible(true)]                                                  //决定是否COM可见
public interface iRSALibary
{
    string RSAGetPubKey();
    string RSAGetPriKey();
    byte[] RSAEncode(ref byte[] plainBytes, string sPubKey);        //对于数组作为参数,一定要加ref,否则VB6中不支持.
    byte[] RSADecode(ref byte[] plainBytes, string sPriKey);
}

[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]     //COM可见,以及接口类型,VB6要调用,必须使用AutoDual
public class cRSA : iRSALibary
{
    private RSACryptoServiceProvider rsa;

    public cRSA()
    {
        rsa = new RSACryptoServiceProvider();
    }

    public string RSAGetPubKey()
    {
        return rsa.ToXmlString(false);
    }

    public string RSAGetPriKey()
    {
        return rsa.ToXmlString(true);
    }

    public byte[] RSAEncode(ref byte[] plainBytes, string sPubKey)
    {
        if (plainBytes == null || plainBytes.Length <= 0)
        {
            throw new NotSupportedException();
        }

        rsa.FromXmlString(sPubKey);

        int bufferSize = (rsa.KeySize / 8) - 11;
        byte[] buffer = new byte[bufferSize];

        using (MemoryStream input = new MemoryStream(plainBytes))
        using (MemoryStream ouput = new MemoryStream())
        {
            while (true)
            {
                int readLine = input.Read(buffer, 0, bufferSize);
                if (readLine <= 0)
                {
                    break;
                }
                byte[] temp = new byte[readLine];
                Array.Copy(buffer, 0, temp, 0, readLine);
                byte[] encrypt = rsa.Encrypt(temp, false);
                ouput.Write(encrypt, 0, encrypt.Length);
            }
            return ouput.ToArray();
        }
    }

    public byte[] RSADecode(ref byte[] plainBytes, string sPriKey)
    {
        if (plainBytes == null || plainBytes.Length <= 0)
        {
            throw new NotSupportedException();
        }

        rsa.FromXmlString(sPriKey);
        int keySize = rsa.KeySize / 8; byte[] buffer = new byte[keySize];

        using (MemoryStream input = new MemoryStream(plainBytes))
        using (MemoryStream output = new MemoryStream())
        {
            while (true)
            {
                int readLine = input.Read(buffer, 0, keySize);
                if (readLine <= 0)
                {
                    break;
                }
                byte[] temp = new byte[readLine];
                Array.Copy(buffer, 0, temp, 0, readLine);
                byte[] decrypt = rsa.Decrypt(temp, false);
                output.Write(decrypt, 0, decrypt.Length);
            }
            return output.ToArray();
        }
    }
}


示例里是封装了.NET中RSA算法,并且解决了RSA不可处理大于128字节内容的问题(采用分段加解密方式处理,代码搬自一名台湾朋友的文章(貌似他也是MSMVP): 点击访问原文 )

其中那个数组的ref问题折腾了我一会儿,之前没加的时候VB6里报错,说是不支持的自动化类型,后来想想可能是引用传递的原因,于是加上ref,果然就OK了lol.gif

三,发布问题.

    发布的时候要注意,由于DLL本身是基于.Net Framework的,因此目标机器上必须得要有对应版本的Framework,此为注意点1.
    注意点2,则是注册DLL的命令不再是Regsvr32,因为此DLL并非标准的COM DLL,要使用.Net中的工具去注册,如下:
    regasm RSALibary.dll /tlb: RSALibary.tlb /codebase
    此命令我已经写在了源码中的reg.bat中.
    
以上一,二两步完成,则C#的DLL工程可以编译了.

第三步即可在目标机器上发布.

编译完成后,如果在第一步里勾选了"自动注册",则会在DLL同目录下生成一个TLB文件,同时会在系统中注册.这个就是VB6中要引用的,DLL本身不能直接引用.

假如没有勾选,那每次编译后,需要自己手工运行一下reg.bat,对于开发机来说,不方便.

至于在VB6中如何使用此DLL中的类,那就与平常的COM对象一样了,就不写了,代码反正已经上传,自己看吧....

压缩包里的C#项目是VS2010版本的,所使用的.Net Framework是2.0版本的.

点击下载
5 条评论
# 1: babytony said:
2016-09-10 22:39:40
N年不见(N>=10),今天偶尔想起,拜访下!
# 2: 嗷嗷叫的老马 said:
2016-10-07 06:53:21
感谢还记得起我,哈哈
# 3: Mradxz said:
2017-07-26 22:10:04
vb6 直接写个不就得了 我记得vbgood 里就有
# 4: 嗷嗷叫的老马 said:
2017-08-30 21:47:34
TO Mradxz:

这不是懒嘛.........想着C#里有现成的,结果实际上折腾更多......
# 5: loquat said:
2017-10-23 20:13:47
这个效率感觉还挺高
添加评论

昵称 *

E-mail