使用 P/Invoke 编组结构时如何忽略字段

发布于 2024-08-11 04:20:00 字数 351 浏览 5 评论 0原文

我想要封送一个与 P/Invoke 一起使用的结构,但该结构包含一个仅与我的托管代码相关的字段,因此我不希望对其进行封送,因为它不属于本机结构。有可能吗?我正在寻找类似于 NonSerialized 的序列化属性,但它似乎不存在......

struct MyStructure
{
    int foo;
    int bar;

    [NotMarshaled] // This attribute doesn't exist, but that's the kind of thing I'm looking for...
    int ignored;
}

任何建议将不胜感激

I want to marshal a structure for use with P/Invoke, but this struct contains a field that is only relevant to my managed code, so I don't want it to be marshaled since it doesn't belong in the native structure. Is it even possible ? I was looking for an attribute similar to NonSerialized for serialization, but it doesn't seem to exist...

struct MyStructure
{
    int foo;
    int bar;

    [NotMarshaled] // This attribute doesn't exist, but that's the kind of thing I'm looking for...
    int ignored;
}

Any suggestion would be appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

诠释孤独 2024-08-18 04:20:00

没有办法让 CLR 忽略某个字段。相反,我会使用两个结构,并且可能使一个结构成为另一个结构的成员。

struct MyNativeStructure 
{ 
    public int foo; 
    public int bar; 
} 

struct MyStructure 
{ 
    public MyNativeStruct native; 
    public int ignored; 
} 

There's no way to make the CLR ignore a field. I would instead use two structures, and perhaps make one a member of the other.

struct MyNativeStructure 
{ 
    public int foo; 
    public int bar; 
} 

struct MyStructure 
{ 
    public MyNativeStruct native; 
    public int ignored; 
} 
冬天的雪花 2024-08-18 04:20:00

两种方法:

  1. 使用类而不是结构:结构始终通过指向 Windows API 或其他本机函数的指针传递。将对 doThis(ref myStruct) 的调用替换为对 doThis([In, Out] myClass) 的调用应该可以解决问题。完成此操作后,您可以简单地使用方法访问未编组的字段。

  2. 正如我已经说过的,结构(几乎)总是通过引用传递:因此被调用者对结构维度一无所知:简单地将附加字段保留在最后一个字段怎么样?当调用需要结构指针和结构大小的本机函数时,只需谎报其大小,给出没有额外字段的情况下的大小。我不知道从本机函数获取此类结构是否是合法的方式。 附带问题:Marshaller 是否处理标记为私有的类字段? (我希望不是...)

Two methods:

  1. Use a class instead of a struct: structures are always passed by pointer to the Windows API or other native functions. Replacing a call to doThis(ref myStruct) with a call to doThis([In, Out] myClass) should do the trick. Once you've done this, you can simply access your not-to-be-marshaled fields with methods.

  2. As i already stated, structs are (almost) always passed by reference: hence the callee knows nothing about structure dimensions: what about simply leaving your additional fields to be the last ones? When calling a native function that needs your structure's pointer and the structure's size, simply lie about its size, giving the one it would have without your extra fields. I don't know if it's a legal way to marshal such a structure back when obtaining it FROM a native function. Side question: does the Marshaller process class fields marked as private? (I hope not...)

柠北森屋 2024-08-18 04:20:00

根据我的测试,自动属性如:

private int marshaled { get; set; }

将在封送时消耗空间(Marshal.SizeOf

但是!明确指定的属性不会:

private int skipped
{
    get { return 0; }
    set { }
} 

based on my tests, auto property like:

private int marshaled { get; set; }

will consume space while marshaling (Marshal.SizeOf)

But! explicitly specified property will not:

private int skipped
{
    get { return 0; }
    set { }
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文