将带有 "ref this" 的结构传递给本机代码是否安全
Is it safe to pass a struct with "ref this" to native code
我目前正在将 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);
}
}
我有点担心将 this
和 ref
传递给本机方法,因为我看到其他实现在传递它之前创建了结构的副本,但我找不到任何东西官方说这样做是安全的还是不安全的。
所以,我的问题是 - 我应该复制还是保留我的解决方案?
在 struct
的实例方法或 属性 中,隐式 this
参数是 ref
托管引用。因此,对结构 do 的任何更改都会改变(更改)传入的结构。
因此,当您调用本机函数时,您传递的是对您自己的结构的实际引用。因此,您的 调用者可能会看到这些更改,如果 他们已经传递了对自己结构的引用。但是根据您的呼叫者如何进行此呼叫,无论如何都可能存在防御性副本。
例如:
var isLocal = SomeClass.IPAddrProperty.IsLocalhost
这将创建该结构的副本,任何更改都将消失。
而这个:
var ipAddr = SomeClass.IPAddrProperty;
var isLocal = ipAddr.IsLocalhost;
SomeClass.IPAddrProperty = ipAddr;
表示将结果复制回来
我目前正在将 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);
}
}
我有点担心将 this
和 ref
传递给本机方法,因为我看到其他实现在传递它之前创建了结构的副本,但我找不到任何东西官方说这样做是安全的还是不安全的。
所以,我的问题是 - 我应该复制还是保留我的解决方案?
在 struct
的实例方法或 属性 中,隐式 this
参数是 ref
托管引用。因此,对结构 do 的任何更改都会改变(更改)传入的结构。
因此,当您调用本机函数时,您传递的是对您自己的结构的实际引用。因此,您的 调用者可能会看到这些更改,如果 他们已经传递了对自己结构的引用。但是根据您的呼叫者如何进行此呼叫,无论如何都可能存在防御性副本。
例如:
var isLocal = SomeClass.IPAddrProperty.IsLocalhost
这将创建该结构的副本,任何更改都将消失。
而这个:
var ipAddr = SomeClass.IPAddrProperty;
var isLocal = ipAddr.IsLocalhost;
SomeClass.IPAddrProperty = ipAddr;
表示将结果复制回来