ฉันมีรหัส C# ที่โต้ตอบกับรหัส C++ ซึ่งดำเนินการกับสตริง
ฉันมีโค้ดชิ้นนี้ในคลาสตัวช่วยแบบคงที่:
internal static unsafe byte* GetConstNullTerminated(string text, Encoding encoding)
{
int charCount = text.Length;
fixed (char* chars = text)
{
int byteCount = encoding.GetByteCount(chars, charCount);
byte* bytes = stackalloc byte[byteCount + 1];
encoding.GetBytes(chars, charCount, bytes, byteCount);
*(bytes + byteCount) = 0;
return bytes;
}
}
อย่างที่คุณเห็น มันจะส่งคืนตัวชี้ไปยังไบต์ที่สร้างด้วยคีย์เวิร์ด stackalloc
อย่างไรก็ตาม จากข้อกำหนด C# 18.8:
บล็อกหน่วยความจำที่จัดสรรสแต็กทั้งหมดที่สร้างขึ้นระหว่างการดำเนินการของสมาชิกฟังก์ชันจะถูกยกเลิกโดยอัตโนมัติเมื่อสมาชิกฟังก์ชันนั้นกลับมา
หมายความว่าตัวชี้ไม่ถูกต้องจริง ๆ ทันทีที่เมธอดส่งคืนใช่หรือไม่
การใช้วิธีนี้ในปัจจุบัน:
byte* bytes = StringHelper.GetConstNullTerminated(value ?? string.Empty, Encoding);
DirectFunction(NativeMethods.SCI_SETTEXT, UIntPtr.Zero, (IntPtr) bytes);
ควรเปลี่ยนรหัสเป็น
...
int byteCount = encoding.GetByteCount(chars, charCount);
byte[] byteArray = new byte[byteCount + 1];
fixed (byte* bytes = byteArray)
{
encoding.GetBytes(chars, charCount, bytes, byteCount);
*(bytes + byteCount) = 0;
}
return byteArray;
และใช้ fixed
อีกครั้งในอาร์เรย์ที่ส่งคืนเพื่อส่งพอยน์เตอร์ไปยังเมธอด DirectFunction
หรือไม่
ฉันกำลังพยายามลดจำนวนการใช้งาน fixed
ให้เหลือน้อยที่สุด (รวมถึงคำสั่ง fixed
ในการโอเวอร์โหลดอื่น ๆ ของ GetByteCount()
และ GetBytes()
จาก Encoding
)
tl;dr
ตัวชี้ไม่ถูกต้องทันทีที่เมธอดส่งคืนหรือไม่ ไม่ถูกต้อง ณ จุดที่ส่งต่อไปยัง
DirectFunction()
หรือไม่หากเป็นเช่นนั้น วิธีที่ดีที่สุดในการใช้คำสั่ง
fixed
น้อยที่สุดเพื่อให้บรรลุภารกิจคืออะไร