gpt4 book ai didi

c# - 如果结构中的字符串长于或短于所使用的p/Invoked签名,会发生什么?

转载 作者:行者123 更新时间:2023-12-01 14:52:33 25 4
gpt4 key购买 nike

举例来说,我想使用C#中的DEV_BROADCAST_DEVICEINTERFACE_A。但是,由于dbcc_name的大小取决于dbcc_size(正式声明为char dbcc_name[1]),因此我不确定如何声明该结构。

根据this question似乎我需要添加

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)]

dbcc_name上。

但是为什么要使用 SizeConst=255?我们不知道大小。 (从我看到的其他答案看来, there is no simple way to declare it such that it will know the correct size或一种根据大小写指定大小的方法。)

因此,如果我在链接的答案中设置了静态长度,会发生什么情况。如果字符串较短或较长,会发生什么?

测试表明,如果更长,我将得到正确的字符串,如果更短,我将得到截断的字符串(例如,如果将SizeConst设置为2,而实际字符串是“abc”,则得到“ab”。)但是我可以确保这是它的工作方式,还是取决于在这种特定情况下恰好可以解决的问题?

最佳答案

您不能完全声明结构,可以执行以下操作:

[StructLayout(LayoutKind.Sequential)]
private struct _DEV_BROADCAST_DEVICEINTERFACE_A
{
public int dbcc_size;
public uint dbcc_devicetype;
public uint dbcc_reserved;
public Guid dbcc_classguid;
public char dbcc_name; // just for offset; don't use!
}

并像这样使用它:
// get ptr to structure from somewhere (lParam from WM_DEVICECHANGE ...)
IntPtr ptr = ...

// read structure
var iface = Marshal.PtrToStructure<_DEV_BROADCAST_DEVICEINTERFACE_A>(ptr);

// get name pointer
var namePtr = ptr + Marshal.OffsetOf<_DEV_BROADCAST_DEVICEINTERFACE_A>(nameof(_DEV_BROADCAST_DEVICEINTERFACE_A.dbcc_name)).ToInt32();

// get name
var name = Marshal.PtrToStringAnsi(namePtr);

请注意,如果名称可以包含零,则应改为将 Marshal.PtrToStringAnsi(namePtr, len)len = dbcc_size - offset of dbcc_name一起使用

关于c# - 如果结构中的字符串长于或短于所使用的p/Invoked签名,会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62178285/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com