电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

关于“跨语言调用”和“CLS(公共语言规范)”


发布日期:2021/1/15
 

的一个很重要的特性就是跨语言的编程用C#写的dll可以在里调用例如

用C#写的一个类编译到dll中然后在中调用

using System;

namespace CLSsample

{

public class CLSTest

{

public CLSTest()

{

}

public void ABC()

{

ConsoleWriteLine(ABC);

}

}

}

在中调用

Dim c As CLSsampleCLSTest = New CLSsampleCLSTest

cABC()

现在给dll中的CLSTest类加一个函数

public void abc()

{

ConsoleWriteLine(abc);

}

先编译C#写的这个dll再编译工程编译出现问题提示信息如下

重载决策失败原因是没有可访问的ABC最适合这些参数:

Public Sub abc(): 不是最适合

Public Sub ABC(): 不是最适合

原因很简单因为C#是区分大小写的但是不区分

而真正的原因在于用C#写的这个类是不符合CLS(公共语言规范)的

现在在命名空间前面加上一句标示编译时确保不包含其它语言无法使用的内容

[assembly:CLSCompliant(true)]

namespace CLSsample

{

public void ABC()

{

ConsoleWriteLine(ABC);

}

public void abc()

{

ConsoleWriteLine(abc);

}

}

这时候再编译就会出现错误提示信息

只在大小写不同的标识符CLSsampleCLSTestabc()不符合 CLS

要编译通过在函数abc前加上

[CLSCompliantAttribute(false)]

指出 abc函数 是不符合 CLS 的

下面是MSDN中对CLS的部分说明

CLS 在设计上足够大可以包括开发人员经常需要的语言构造同时也足够小

大多数语言都可以支持它此外任何不可能快速验证代码类型安全性的语言

构造都被排除在 CLS 之外以便所有符合 CLS 的语言都可以生成可验证的代码

(如果它们选择这样做)

也就是说开发的类库必须遵守CLS才可以更好的被其它的语言所使用否则就像

上面的情况用C#开发的动态链接库在中就出现了问题特别是开发一些

通用的类库的时候就更需要注意这一点

看看 framework中Int反编译的部分结果(用的是Reflector):

[CLSCompliant(false)]

uint SystemIConvertibleToUInt(IFormatProvider provider);

这是因为有的语言不支持UInt类型

再看看对UInt反编译的结果UInt的声明

[Serializable StructLayout(LayoutKindSequential) CLSCompliant(false)]

public struct UInt : IComparable IFormattable IConvertible

{

}

在前阵子的一个随笔什么是CLS?

CLS是编程语言设计者和类库设计者之间的一个约定

现在体会得更深了

刚开始系统学框架有错误的地方还请大家不吝赐教

上一篇:鲜为人知的Windows XP优化

下一篇:Windows8多个显示器设置更炫更个性