首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ArrayList编组与useLegacyV2RuntimeActivationPolicy

ArrayList编组与useLegacyV2RuntimeActivationPolicy
EN

Stack Overflow用户
提问于 2022-09-29 22:08:43
回答 1查看 123关注 0票数 5

我注意到,如果我有一个.NET Framework4.8程序集,该程序集公开了一个接受System.Collections.ArrayList参数的COM互操作方法,然后从VB6调用该方法,则.NET方法将获得ArrayList的副本,而不是传递的原始ArrayListGetHashCode()在VB6对象上返回不同的值,而不是在.NET对象上返回不同的值;如果.NET方法修改ArrayList,则不会对VB6侧的对象进行修改。

但是,如果在.exe.config文件中添加了一个<startup useLegacyV2RuntimeActivationPolicy="true">部分,它将按预期的方式工作:GetHashCode()在VB6和.NET边返回相同的值,而.NET方法所做的修改在VB6端看到。

这一切为什么要发生?有什么方法可以让它在不设置useLegacyV2RuntimeActivationPolicy="true"的情况下按我预期的方式工作吗?(我不介意把它设置为真,我主要好奇为什么要这样做才能奏效)

详细信息:

我在.NET端使用了这个选项,并在项目构建配置上检查了“”。

代码语言:javascript
运行
复制
using System.Collections;
using System.Runtime.InteropServices;

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class ItemAdder
{
    public int AddItem(ArrayList ar)
    {
        ar.Add("def");
        return ar.GetHashCode();
    }
}

在VB6端,创建项目,向C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb添加一个项目引用,并将其放入模块中:

代码语言:javascript
运行
复制
Option Explicit

Sub Main()
  Dim al As New ArrayList
  Dim adder As New ItemAdder
  Dim msg As String
  
  al.Add "abc"
  msg = "HashCode in VB6 is: " & al.GetHashCode() & vbCrLf
  msg = msg & "HashCode in .NET is: " & adder.AddItem(al) & vbCrLf
  msg = msg & "Item was " & IIf(al.Count <= 1, "not ", "") & "added"
  MsgBox msg
End Sub

.exe.config文件(如果从VB6 IDE运行,或者如果将VB6项目编译为EXE,则可以将其用作EXE的.config文件):

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
  </startup>
</configuration>

如果是useLegacyV2RuntimeActivationPolicy="true",则MsgBox将两个HashCodes显示为相等,并显示添加了该项。如果是useLegacyV2RuntimeActivationPolicy="false",则MsgBox显示不同的HashCodes,并且没有添加该项。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-30 06:51:11

这是因为从COM的角度来看,ArrayList是建立在.NET框架的旧版本之上的。

ArrayList COM注册为64位,在mscorlib.dll中构建在.NET框架2上:

ArrayList COM在32位(64位系统上)注册,在mscorlib.dll中基于.NET框架1:

因此,如果您使用.dll框架4构建.NET,并从VB6 (32位)调用它,您将在同一个过程中混合不同版本(这里的版本为4和1),这会产生问题。

元素上的正式文档所述

如果应用程序使用遗留激活路径..。您希望这些路径激活CLR的版本4,而不是更早的版本,或者如果您的应用程序是用.NET框架4构建的,但是依赖于使用.NET框架的早期版本构建的混合模式程序集,那么仅在支持的运行时列表中指定.NET Framework4是不够的。此外,在配置文件中的元素中,必须将useLegacyV2RuntimeActivationPolicy属性设置为true。..。

这基本上是一个“魔术”开关,如下所述:useLegacyV2RuntimeActivationPolicy是干什么用的?

useLegacyV2RuntimeActivationPolicy属性基本上允许您说:“我对遗留的shim有一些依赖关系。请让他们按照他们以前选择的运行时的方式工作。

也来自同一链接:

最终,这个属性与“遗留的shim”的行为有关。您可以认为这些包含了几类CLR激活: ..。 Pre-v4com激活-这包括CoCreateInstance的CLSID (或类型标识符),其最新的注册是针对的前v4运行时版本。注意,这包括托管代码中的这种co类上的“新”操作符,或者Activator.CreateInstance对Type.GetTypeFromCLSID在这样一个CLSID上创建的类型的结果。 前v4 IJW (混合模式)激活??例如,在这样的程序集上调用本机导出。 本机运行时的本机激活--提供的COM CLSID --例如ICLRRuntimeHost的CLSID上的CoCreateInstance 托管框架CLSID的原生激活--比如System.ArrayList的CLSID (非常罕见的) CoCreateInstance

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73902133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档