C++/CLI .obj 和 C# .netmodule 之间的 LNK2022 部分 class
LNK2022 between C++/CLI .obj and C# .netmodule with partial class
在尝试使用混合语言程序集(例如 here or here)时,我遇到了一些奇怪的 link 错误。我不是在寻找 "don't do that" 建议或替代方案,而是想了解这些错误的含义,因为从表面上看它们都没有多大意义。
C#代码:
// csppStub.cs
public static partial class To
{
static partial void Do();
extern public static bool Done();
}
C++代码:
// cspp.cpp
public ref class To abstract sealed
{
// lnk2022 metadata operation failed (801311D6):
// Differing number of methods in duplicated types (To): (0x02000002).
static void Do() { }
// lnk2022 metadata operation failed (801311D8):
// Differing number of parameters in duplicated method (types: To; methods: Done): (0x06000001).
public: static bool Done() { return true; }
};
VS 2015 项目文件:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>cspp</ProjectName>
<ProjectGuid>{A6FF913B-C27A-4CBC-A847-B15CFA7AE80F}</ProjectGuid>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup>
<_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Link>
<AdditionalDependencies>$(OutDir)\csppStub.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<ClCompile>
<CompileAsManaged>true</CompileAsManaged>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cspp.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsManaged>
<ExceptionHandling Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Async</ExceptionHandling>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="csppStub.cs">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">csc /target:module /out:$(OutDir)\csppStub.netmodule csppStub.cs</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)\csppStub.netmodule</Outputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
构建输出:
Error LNK2022 metadata operation failed (801311D8): Differing number of parameters in duplicated method (types: To; methods: Done): (0x06000001).
Error LNK2022 metadata operation failed (801311D6): Differing number of methods in duplicated types (To): (0x02000002).
链接器被您尝试做的事情弄糊涂了,所以它的诊断不是很好。 C++/CLI 代码中的一个常见问题是它可能会在多个目标文件中遇到相同的 ref class 声明。由#include 指令引起。在 C# 中从未发生过的事情,partial
关键字解析为 compile-time。
链接器必须对此做一些事情,它需要将这些重复项过滤成一个它可以在元数据中发出的定义。它执行测试以确保 class 定义完全相同。 LNK2022 当它们不存在时。常见的原因是宏或不同的编译选项。
但在这种情况下,重复项来自 C# 和 C++/CLI 声明。放弃所有的希望,那永远不会是一场比赛。 extern
关键字并没有像你想的那样做,它是抖动的一个指令,告诉它需要在别处找到函数。它知道的其他地方不多,也不是可扩展的,仅限于 CLR 实现的功能、[DllImport] 声明和 COM 互操作。
元数据中根本没有类似于 partial
的机制。您将不得不考虑采用您在 .NET 中执行此操作的常规无聊方式、继承和多态性。 C++/CLI class 可以使用 C# class 作为基础,C# class 可以是 abstract
.
在尝试使用混合语言程序集(例如 here or here)时,我遇到了一些奇怪的 link 错误。我不是在寻找 "don't do that" 建议或替代方案,而是想了解这些错误的含义,因为从表面上看它们都没有多大意义。
C#代码:
// csppStub.cs
public static partial class To
{
static partial void Do();
extern public static bool Done();
}
C++代码:
// cspp.cpp
public ref class To abstract sealed
{
// lnk2022 metadata operation failed (801311D6):
// Differing number of methods in duplicated types (To): (0x02000002).
static void Do() { }
// lnk2022 metadata operation failed (801311D8):
// Differing number of parameters in duplicated method (types: To; methods: Done): (0x06000001).
public: static bool Done() { return true; }
};
VS 2015 项目文件:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>cspp</ProjectName>
<ProjectGuid>{A6FF913B-C27A-4CBC-A847-B15CFA7AE80F}</ProjectGuid>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<CLRSupport>true</CLRSupport>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup>
<_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Link>
<AdditionalDependencies>$(OutDir)\csppStub.netmodule;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<ClCompile>
<CompileAsManaged>true</CompileAsManaged>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cspp.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsManaged>
<ExceptionHandling Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Async</ExceptionHandling>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="csppStub.cs">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">csc /target:module /out:$(OutDir)\csppStub.netmodule csppStub.cs</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)\csppStub.netmodule</Outputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
构建输出:
Error LNK2022 metadata operation failed (801311D8): Differing number of parameters in duplicated method (types: To; methods: Done): (0x06000001).
Error LNK2022 metadata operation failed (801311D6): Differing number of methods in duplicated types (To): (0x02000002).
链接器被您尝试做的事情弄糊涂了,所以它的诊断不是很好。 C++/CLI 代码中的一个常见问题是它可能会在多个目标文件中遇到相同的 ref class 声明。由#include 指令引起。在 C# 中从未发生过的事情,partial
关键字解析为 compile-time。
链接器必须对此做一些事情,它需要将这些重复项过滤成一个它可以在元数据中发出的定义。它执行测试以确保 class 定义完全相同。 LNK2022 当它们不存在时。常见的原因是宏或不同的编译选项。
但在这种情况下,重复项来自 C# 和 C++/CLI 声明。放弃所有的希望,那永远不会是一场比赛。 extern
关键字并没有像你想的那样做,它是抖动的一个指令,告诉它需要在别处找到函数。它知道的其他地方不多,也不是可扩展的,仅限于 CLR 实现的功能、[DllImport] 声明和 COM 互操作。
元数据中根本没有类似于 partial
的机制。您将不得不考虑采用您在 .NET 中执行此操作的常规无聊方式、继承和多态性。 C++/CLI class 可以使用 C# class 作为基础,C# class 可以是 abstract
.