Problem marshalling with Unmanaged.LPUTF8Str #52810
-
|
I didn't want to file this as a bug because I think I'm causing the problem but I don't know why. I'm updating our Vulkan library P/Invokes and interop structures to .NET5 where we can use the The problem is though, that the method [DllImport(VulkanLibrary.Name)] static extern void vkGetPhysicalDeviceProperties(IntPtr physicalDevice, out VkPhysicalDeviceProperties properties);throws some memory exception with the struct given below. The docs explicitly say that it is a nul-terminated UTF8 string so I thought it should work. What does work is using [StructLayout(LayoutKind.Sequential)]
public readonly struct VkPhysicalDeviceProperties
{
public readonly VulkanVersion ApiVersion;
public readonly VulkanVersion DriverVersion;
public readonly int VendorId;
public readonly int DeviceId;
public readonly VkPhysicalDeviceType DeviceType;
// The docs say that it is an UTF8 (nul-terminated) string, the question is why LPUTF8Str doesn't work.
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxPhysicalDeviceNameSize)]
public readonly string DeviceName;
public readonly Guid PipelineCacheUuid;
public readonly VkPhysicalDeviceLimits Limits;
public readonly VkPhysicalDeviceSparseProperties SparseProperties;
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
|
The difference between For the struct VkPhysicalDeviceProperties
{
VulkanVersion ApiVersion;
VulkanVersion DriverVersion;
int VendorId;
int DeviceId;
VkPhysicalDeviceType DeviceType;
char DeviceName[MaxPhysicalDeviceNameSize]; // Marshalled in-place in the structure
GUID PipelineCacheUuid;
VkPhysicalDeviceLimits Limits;
VkPhysicalDeviceSparseProperties SparseProperties;
};For the LPUTF8Str case, the string is marshalled as a pointer to the allocated string, so the struct would look like the following: struct VkPhysicalDeviceProperties
{
VulkanVersion ApiVersion;
VulkanVersion DriverVersion;
int VendorId;
int DeviceId;
VkPhysicalDeviceType DeviceType;
char* DeviceName; // Marshalled as a pointer
GUID PipelineCacheUuid;
VkPhysicalDeviceLimits Limits;
VkPhysicalDeviceSparseProperties SparseProperties;
};From what it sounds like, the ByValTStr case has the matching layout to the native code, which would be why it works and why the LPUTF8Str case does not. |
Beta Was this translation helpful? Give feedback.
The difference between
ByValTStrandLPUTF8Stris where the string is placed in memory.For the
ByValTStrcase, the native representation of theVkPhysicalDevicePropertiesstruct would look like the following:For the LPUTF8Str case, the string is marshalled as a poin…