使用“ref this”传递结构是否安全?到本机代码

发布于 2025-01-11 11:32:38 字数 1270 浏览 0 评论 0原文

我目前正在将 Steamworks SDK 集成到我的游戏中,并且有一些方法需要将结构体作为指针传递,例如:

// Public interface method declared by the library
S_API bool SteamAPI_SteamNetworkingIPAddr_IsLocalHost( SteamNetworkingIPAddr* self );
// C# implementation

[StructLayout(LayoutKind.Explicit, Size = 18, Pack = 1)]
public struct SteamNetworkingIPAddr {

    // My current usage of "ref this"
    public bool IsLocalhost => NativeMethods.SteamAPI_SteamNetworkingIPAddr_IsLocalHost(ref this);

    // How another library solves it
    public bool IsLocalhost {
        get {
            SteamNetworkingIPAddr copy = this;
            NativeMethods.SteamAPI_SteamNetworkingIPAddr_IsLocalHost(ref self);
        }
    }


    private static class NativeMethods {
        [DllImport(SteamAPI.LIBRARY_NAME, EntryPoint = "SteamAPI_SteamNetworkingIPAddr_IsLocalHost", CallingConvention = CallingConvention.Cdecl)]
        internal static extern bool SteamAPI_SteamNetworkingIPAddr_IsLocalHost(ref SteamNetworkingIPAddr self);
    }
}

我有点担心用 ref< 传递 this /code> 到本机方法,因为我见过其他实现在传递结构之前创建结构的副本,但我找不到正式说明这样做是安全或不安全的东西。

所以,我的问题是 - 我应该复制还是保留我的解决方案?

I am currently integrating the Steamworks SDK into my game and have a couple of methods which require to pass a struct as a pointer, for example:

// Public interface method declared by the library
S_API bool SteamAPI_SteamNetworkingIPAddr_IsLocalHost( SteamNetworkingIPAddr* self );
// C# implementation

[StructLayout(LayoutKind.Explicit, Size = 18, Pack = 1)]
public struct SteamNetworkingIPAddr {

    // My current usage of "ref this"
    public bool IsLocalhost => NativeMethods.SteamAPI_SteamNetworkingIPAddr_IsLocalHost(ref this);

    // How another library solves it
    public bool IsLocalhost {
        get {
            SteamNetworkingIPAddr copy = this;
            NativeMethods.SteamAPI_SteamNetworkingIPAddr_IsLocalHost(ref self);
        }
    }


    private static class NativeMethods {
        [DllImport(SteamAPI.LIBRARY_NAME, EntryPoint = "SteamAPI_SteamNetworkingIPAddr_IsLocalHost", CallingConvention = CallingConvention.Cdecl)]
        internal static extern bool SteamAPI_SteamNetworkingIPAddr_IsLocalHost(ref SteamNetworkingIPAddr self);
    }
}

I am a bit concerned about passing this with ref to the native method because I've seen other implementations which create a copy of the struct before passing it but I could not find something which officially says that it's either safe or unsafe to do so.

So, my question is - should I make a copy or keep my solution?

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

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

发布评论

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

评论(1

我很OK 2025-01-18 11:32:38

struct 的实例方法或属性中,隐式 this 参数是 ref 托管引用。因此,对结构体的任何更改都会改变(更改)传入的结构体。

因此,当您调用本机函数时,您正在传递对您自己的结构体的实际引用。因此,您的调用者有可能看到这些更改,如果他们传入了对其自己的结构的引用。但根据呼叫者如何进行此呼叫,无论如何都可能存在防御性副本。

例如:

var isLocal = SomeClass.IPAddrProperty.IsLocalhost

这将创建结构的副本,任何更改都将消失。

而这:

var ipAddr = SomeClass.IPAddrProperty;
var isLocal = ipAddr.IsLocalhost;
SomeClass.IPAddrProperty = ipAddr;

意味着结果被复制回来。

In a instance method or property of a struct, the implicit this parameter is a ref managed reference. So any changes to the struct do mutate (change) the struct passed in.

Therefore, when you call the native function, you are passing an actual reference to your own struct. So it is possible for your caller to see these changes, if they have passed in a reference to their own struct. But depending on how your caller makes this call, there may be a defensive copy anyway.

For example:

var isLocal = SomeClass.IPAddrProperty.IsLocalhost

this will create a copy of the struct, and any changes will disappear.

Whereas this:

var ipAddr = SomeClass.IPAddrProperty;
var isLocal = ipAddr.IsLocalhost;
SomeClass.IPAddrProperty = ipAddr;

means that the results are copied back.

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