You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#源生成器原生封送:如何使用其他程序集定义的类型?

解决共享项目中PInvoke自定义封送器的MarshalDirectiveException问题

以下是几个直接可行的修复方案,按优先级排序:

1. 确保调用项目正确配置源生成器支持

共享项目本身不独立编译,依赖调用项目的编译环境,必须在调用项目的.csproj中明确启用源生成器相关配置:

  • 添加必要的NuGet包引用:
    <ItemGroup>
      <PackageReference Include="System.Runtime.InteropServices.Marshalling" Version="8.0.0" PrivateAssets="all" />
    </ItemGroup>
    
  • 启用预览特性和源生成PInvoke:
    <PropertyGroup>
      <EnablePreviewFeatures>true</EnablePreviewFeatures>
      <EnableSourceGeneratedPInvokes>true</EnableSourceGeneratedPInvokes>
      <LangVersion>12</LangVersion> <!-- 或对应支持的C#版本,需匹配SDK版本 -->
    </PropertyGroup>
    

2. 显式标记共享项目中的可封送类型

给共享项目里的结构体/record添加[StructLayout]特性,同时确保MarshalUsing和CustomMarshaller的定义完整且可访问:

// 共享项目中的示例类型
[StructLayout(LayoutKind.Sequential)]
[MarshalUsing(typeof(MyStructMarshaller))]
public struct MyStruct
{
    public int Value;
}

// 自定义封送器(可放在共享项目或调用项目中)
[CustomMarshaller(typeof(MyStruct), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerImpl))]
public static class MyStructMarshaller
{
    public class MarshallerImpl
    {
        public IntPtr ConvertToUnmanaged(MyStruct managed)
        {
            var ptr = Marshal.AllocHGlobal(Marshal.SizeOf<int>());
            Marshal.WriteInt32(ptr, managed.Value);
            return ptr;
        }

        public void Free(IntPtr unmanaged)
        {
            Marshal.FreeHGlobal(unmanaged);
        }
    }
}

3. 将共享项目改为类库项目

如果上述配置无效,直接把共享项目转换成类库项目(Class Library):

  • 这样项目会编译成带有完整元数据的DLL,源生成器能正确识别类型上的封送特性,避免因共享项目代码嵌入导致的元数据丢失问题。
  • 调用项目直接引用这个类库项目即可。

4. 强制源生成器扫描共享项目代码

在调用项目的.csproj中添加额外文件引用,确保源生成器能扫描到共享项目的所有代码文件:

<ItemGroup>
  <AdditionalFiles Include="..\YourSharedProject\**\*.cs" />
</ItemGroup>

问题本质

共享项目的代码是嵌入到调用项目中编译的,如果源生成器没有正确扫描到共享项目类型上的MarshalUsing/CustomMarshaller特性,会 fallback 到传统封送逻辑。此时生成的泛型PInvoke代码会触发非blittable类型的封送限制,抛出MarshalDirectiveException。将类型移到调用项目时,源生成器能直接捕获到特性,生成正确的自定义封送代码,因此不会报错。

内容的提问来源于stack exchange,提问作者Johann Studanski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:18:14