Tôi cần sắp xếp một số cấu trúc lồng nhau trong C# 4.0 thành các đốm màu nhị phân để chuyển sang khung công tác C++.C# interop: tương tác xấu giữa cố định và MarshalAs
Tôi cho đến nay đã có rất nhiều thành công khi sử dụng unsafe
/fixed
để xử lý các mảng độ dài cố định của các loại nguyên thủy. Bây giờ tôi cần xử lý một cấu trúc chứa các mảng chiều dài cố định lồng nhau của các cấu trúc khác.
Tôi đã sử dụng cách giải quyết phức tạp làm phẳng cấu trúc nhưng sau đó tôi đã xem qua một ví dụ về thuộc tính MarshalAs
trông giống như nó có thể giúp tôi tiết kiệm rất nhiều vấn đề.
Thật không may trong khi nó cho tôi số tiền chính xác dữ liệu dường như cũng ngăn không cho các mảng fixed
được sắp xếp đúng cách, do đầu ra của chương trình này thể hiện. Bạn có thể xác nhận lỗi bằng cách đặt điểm ngắt trên dòng cuối cùng và kiểm tra bộ nhớ tại mỗi con trỏ.
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace MarshalNested
{
public unsafe struct a_struct_test1
{
public fixed sbyte a_string[3];
public fixed sbyte some_data[12];
}
public struct a_struct_test2
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public sbyte[] a_string;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public a_nested[] some_data;
}
public unsafe struct a_struct_test3
{
public fixed sbyte a_string[3];
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public a_nested[] some_data;
}
public unsafe struct a_nested
{
public fixed sbyte a_notherstring[3];
}
class Program
{
static unsafe void Main(string[] args)
{
a_struct_test1 lStruct1 = new a_struct_test1();
lStruct1.a_string[0] = (sbyte)'a';
lStruct1.a_string[1] = (sbyte)'b';
lStruct1.a_string[2] = (sbyte)'c';
a_struct_test2 lStruct2 = new a_struct_test2();
lStruct2.a_string = new sbyte[3];
lStruct2.a_string[0] = (sbyte)'a';
lStruct2.a_string[1] = (sbyte)'b';
lStruct2.a_string[2] = (sbyte)'c';
a_struct_test3 lStruct3 = new a_struct_test3();
lStruct3.a_string[0] = (sbyte)'a';
lStruct3.a_string[1] = (sbyte)'b';
lStruct3.a_string[2] = (sbyte)'c';
IntPtr lPtr1 = Marshal.AllocHGlobal(15);
Marshal.StructureToPtr(lStruct1, lPtr1, false);
IntPtr lPtr2 = Marshal.AllocHGlobal(15);
Marshal.StructureToPtr(lStruct2, lPtr2, false);
IntPtr lPtr3 = Marshal.AllocHGlobal(15);
Marshal.StructureToPtr(lStruct3, lPtr3, false);
string s1 = "";
string s2 = "";
string s3 = "";
for (int x = 0; x < 3; x++)
{
s1 += (char) Marshal.ReadByte(lPtr1+x);
s2 += (char) Marshal.ReadByte(lPtr2+x);
s3 += (char) Marshal.ReadByte(lPtr3+x);
}
Console.WriteLine("Ptr1 (size " + Marshal.SizeOf(lStruct1) + ") says " + s1);
Console.WriteLine("Ptr2 (size " + Marshal.SizeOf(lStruct2) + ") says " + s2);
Console.WriteLine("Ptr3 (size " + Marshal.SizeOf(lStruct3) + ") says " + s3);
Thread.Sleep(10000);
}
}
}
Output:
Ptr1 (size 15) says abc
Ptr2 (size 15) says abc
Ptr3 (size 15) says a
Vì vậy, đối với một số lý do nó chỉ marshalling ký tự đầu tiên của chuỗi fixed
ANSI của tôi. Có cách nào xung quanh điều này không, hay tôi đã làm điều gì đó ngu ngốc không liên quan đến sự đầm lầy?
Ngăn xếp ngăn xếp: Nhận danh tiếng để chỉnh sửa bài đăng của mọi người và tài liệu MSDN đáng chú ý. Đặt một câu hỏi khó? [Dế] –
Bạn ít nhất có được một huy hiệu tumbleweed;) Và bây giờ với tiền thưởng, bạn sẽ nhận được sự chú ý của dev tốt hơn * nhưng không cần thái độ *. –
Bạn đã từng sử dụng trang web này trước đây chưa? Nó chạy trên thái độ xấu. :-P –