<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      C#與C++動(dòng)態(tài)鏈接庫(kù)數(shù)據(jù)傳遞

      1 內(nèi)存對(duì)齊規(guī)則

      • 結(jié)構(gòu)體的數(shù)據(jù)成員,第一個(gè)成員的偏移量為0,后面每個(gè)成員變量的地址必須從其大小的整數(shù)倍開始。
      • 子結(jié)構(gòu)體中的第一個(gè)成員偏移量應(yīng)當(dāng)是子結(jié)構(gòu)體中最大成員的整數(shù)倍。
      • 結(jié)構(gòu)體的總大小必須是其內(nèi)部最大成員的整數(shù)倍

      示例

      #include <iostream>
      using namespace std;
      struct Frame {
          unsigned char id; // 0-1
          int width; // 4-8
          long long height; // 8-16
          unsigned char* data; // 16-24 (x64) 16-20 (x86) 指針x86下是4字節(jié)
          int size; // 24-28
      };
      struct Info {
          char name[10];//0-10
          double value;	//16-24
          Frame fr; // 24-56
      };
      
      int main() {
      	Frame frame;
      	Info info;
          cout << sizeof(frame) << endl;//輸出32(x64) 輸出24(x86)
      	cout << sizeof(info) << endl;//輸出56(x64) 輸出48(x86)
      }

      在 C++ 中,我們可以使用 #pragma pack(n) 來(lái)修改對(duì)齊方式,控制結(jié)構(gòu)體中成員的排列方式。

      • n 可以是 1、2、4、8、16 等,表示最大對(duì)齊數(shù)為 n 字節(jié)。

      • #pragma pack(1) 表示取消對(duì)齊,所有成員緊密排列,沒有插入任何 padding。

      使用 #pragma pack 有利于節(jié)省內(nèi)存空間,但會(huì)降低訪問(wèn)效率,甚至引發(fā)硬件異常(部分平臺(tái)不支持非對(duì)齊訪問(wèn))。

      #pragma pack(push, 1)
      struct Frame {
          unsigned char id; //0-1
          int width;//1-5
          long long height;//5-13
          unsigned char* data;//13-21(x64)
          int size;//21-25
      };
      #pragma pack(pop)

      此時(shí)Frame的大小變成了25。

      2 C#結(jié)構(gòu)體

      示例

      using System.Runtime.InteropServices;
      
      class Program
      {
          struct Frame
          {
              byte id; // 0-1
              int width; // 4-8
              long height; // 8-16
              int size; // 16-20
          };
          static void Main()
          {
              Frame fr = new Frame();
              int len = Marshal.SizeOf(fr);//24
              Console.WriteLine("Size of Frame: " + len);
          }
      }

      在 C# 中,結(jié)構(gòu)體的內(nèi)存布局控制是通過(guò)特性(Attributes)來(lái)實(shí)現(xiàn)的,特別是 [StructLayout][FieldOffset]

      ? 示例一:順序布局 Sequential

      [StructLayout(LayoutKind.Sequential)]
      struct Frame //結(jié)構(gòu)體大小24字節(jié)
      {
          byte id;          // 0-1
          int width;        // 4-8
          long height;      // 8-16
          int size;         // 16-20
      }

      ? 示例二:精確偏移 Explicit

      [StructLayout(LayoutKind.Explicit)]
      struct Frame //結(jié)構(gòu)體大小48字節(jié)
      {
          [FieldOffset(0)] byte id;       //0-1
          [FieldOffset(10)] int width;    //10-14
          [FieldOffset(15)] long height;  //15-23
          [FieldOffset(40)] int size;     //40-48
      }

      ? 示例三:模擬 #pragma pack(1)

      [StructLayout(LayoutKind.Sequential, Pack = 1)]
      struct Frame //結(jié)構(gòu)體大小17字節(jié)
      {
          byte id;     //0-1
          int width;   //1-5
          long height; //5-13
          int size;    //13-17
      }

      3 調(diào)用約定

      __cdecl 是 C/C++ 的默認(rèn)調(diào)用約定,參數(shù)從右向左入棧,調(diào)用者負(fù)責(zé)清理?xiàng)!KС挚勺儏?shù)函數(shù)(如 printf),跨平臺(tái)兼容性好。在 C# 調(diào)用時(shí)應(yīng)指定 CallingConvention.Cdecl,適合自己寫的 DLL。

      __stdcall 是 Windows API 常用的調(diào)用約定,參數(shù)也是從右向左入棧,但由被調(diào)用者清理?xiàng)?臻g。函數(shù)名導(dǎo)出時(shí)會(huì)被修飾(如 _Func@8),不支持可變參數(shù)。C# 默認(rèn)用它,常用于調(diào)用系統(tǒng) DLL 或標(biāo)準(zhǔn)第三方庫(kù)。

      4 C#與C++之間類型的對(duì)應(yīng)關(guān)系

      C# 類型
      C++ 對(duì)應(yīng)類型
      ?? 差異說(shuō)明
      byte
      unsigned char
      ? 完全匹配,8 位無(wú)符號(hào)整數(shù)(0~255)
      sbyte
      signed char / char
      ? 對(duì)應(yīng)有符號(hào) 8 位整數(shù)(-128~127)
      short
      short
      ? 都是 16 位有符號(hào)整數(shù)
      ushort
      unsigned short
      ? 都是 16 位無(wú)符號(hào)整數(shù)
      int
      int
      ? Windows 上都是 32 位有符號(hào)整數(shù)
      uint
      unsigned int
      ? 32 位無(wú)符號(hào)整數(shù)
      long
      long long
      ?? C++ 的 long 是 4 字節(jié),C# 的 long 是 8 字節(jié),建議對(duì)應(yīng) long long
      float
      float
      ? 都是 32 位浮點(diǎn)數(shù)
      double
      double
      ? 都是 64 位浮點(diǎn)數(shù)
      IntPtr
      void* / 指針類型
      ? 平臺(tái)相關(guān)的指針地址(x86 是 4 字節(jié),x64 是 8 字節(jié))
      byte[] + [MarshalAs(...)]
      unsigned char buffer[固定大小]
      ? 用于定長(zhǎng)字節(jié)數(shù)組傳遞,必須指定大小

      4.1 基本數(shù)據(jù)類型傳遞

      1. 通過(guò)值傳遞基本類型參數(shù) (Pass by Value):傳遞的是參數(shù)的值,函數(shù)內(nèi)部修改不會(huì)影響調(diào)用方

      • C++:void Test_BasicData(unsigned char b, short s, int i, long long l, float f, double d);

      • C#:  Test_BasicData(char b, short s, int i, long l, float f, double d);

      2. 通過(guò)引用傳遞基本類型參數(shù) (Pass by Reference):傳遞參數(shù)的引用,函數(shù)內(nèi)部修改會(huì)反映到調(diào)用方
      • C++:void Test_BasicDataRef(char &b, short &s, int &i, long long &l, float &f, double &d);

      • C#:Test_BasicDataRef(ref char b, ref short s, ref int i, ref long l, ref float f, ref double d);

      3. 通過(guò)指針傳遞基本類型參數(shù) (Pass by Pointer): C# 使用 ref 來(lái)傳遞指針,通過(guò) char*short* 等 C++ 指針類型,C++ 可以直接修改傳入的變量。這種方式通常用于需要通過(guò) C++ 修改大量數(shù)據(jù)或處理復(fù)雜數(shù)據(jù)結(jié)構(gòu)的場(chǎng)景

      • C++:void Test_BasicDataPoint(char* b, short* s, int* i, long long* l, float* f, double* d);

      • C#:Test_BasicDataPoint(ref char b, ref short s, ref int i, ref long l, ref float f, ref double d);

      完整代碼

      // =================== C# 文件:Program.cs ===================
      using System;
      using System.Runtime.InteropServices;
      
      class Program
      {
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern void Test_BasicData(char b, short s, int i, long l, float f, double d);
      
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern void Test_BasicDataRef(ref char b, ref short s, ref int i, ref long l, ref float f, ref double d);
      
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern void Test_BasicDataPoint(ref char b, ref short s, ref int i, ref long l, ref float f, ref double d);
      
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern int Add(int a, int b);
      
          static void Main()
          {
              Test_BasicData('a', 1, 2, 3, 4.0f, 5.0);
      
              char b = 'a';
              short s = 1;
              int i = 2;
              long l = 3;
              float f = 4.0f;
              double d = 5.0;
      
              Test_BasicDataRef(ref b, ref s, ref i, ref l, ref f, ref d);
              Test_BasicDataPoint(ref b, ref s, ref i, ref l, ref f, ref d);
      
              int n = Add(1, 3);
              Console.WriteLine($"Add result: {n}");
      
              Console.Read();
          }
      }
      // =================== C++ 文件:mylib.cpp ===================
      #include <windows.h>
      #include <stdio.h>
      #include <iostream>
      using namespace std;
      
      extern "C" __declspec(dllexport) int Add(int a, int b);
      
      extern "C" __declspec(dllexport) void Test_BasicData(unsigned char b, short s, int i, long long l, float f, double d);
      
      extern "C" __declspec(dllexport) void Test_BasicDataRef(char &b, short &s, int& i, long long& l, float& f, double& d);
      
      extern "C" __declspec(dllexport) void Test_BasicDataPoint(char* b, short* s, int* i, long long* l, float* f, double* d);
      
      int Add(int a, int b)
      {
          return a + b;
      }
      
      void Test_BasicData(unsigned char b, short s, int i, long long l, float f, double d) 
      {
          cout << "Test_BasicData: " << b << ", " << s << ", " << i << ", " << l << ", " << f << ", " << d << endl;
      }
      
      void Test_BasicDataRef(char& b, short& s, int& i, long long& l, float& f, double& d)
      {
          b += 1; s += 2; i += 3; l += 4; f += 5; d += 6;
          cout << "Test_BasicDataRef modified values.\n";
      }
      
      void Test_BasicDataPoint(char* b, short* s, int* i, long long* l, float* f, double* d)
      {
          *b += 11; *s += 22; *i += 33; *l += 44; *f += 55; *d += 66;
          cout << "Test_BasicDataPoint modified values.\n";
      }

      [DllImport] 參數(shù)簡(jiǎn)要說(shuō)明

      • "mylib.dll":指定要加載的 DLL 文件名。

      • CallingConvention:指定調(diào)用約定,通常用 Cdecl 與 C++ 函數(shù)匹配。

      • EntryPoint:顯式指定要調(diào)用的函數(shù)名,用于解決名稱不一致的問(wèn)題。

      • CharSet:設(shè)置字符串編碼方式(如 AnsiUnicode)。

      • ExactSpelling:禁止根據(jù) CharSet 自動(dòng)添加后綴(如 A/W)。

      4.2 數(shù)組傳遞

      • C# 的數(shù)組可以直接傳給 C++,如 int[] 對(duì)應(yīng) int*。因?yàn)?strong> C++ 無(wú)法知道數(shù)組長(zhǎng)度,需額外傳遞一個(gè) size 參數(shù)表示元素?cái)?shù)量。內(nèi)存是順序連續(xù)的,C++ 端可以正常遍歷使用。

      • C++ 返回?cái)?shù)組時(shí)需使用靜態(tài)或堆內(nèi)存,不能返回局部變量。C# 端使用 IntPtr 接收,再通過(guò) Marshal.Copy 復(fù)制為托管數(shù)組。如果 C++ 返回的是堆內(nèi)存(動(dòng)態(tài)分配的內(nèi)存),C# 端必須調(diào)用 C++ 提供的釋放函數(shù),否則內(nèi)存會(huì)泄漏。

      示例

      // ============== C# 代碼 ==============
      
      using System;
      using System.Runtime.InteropServices;
      
      class Program
      {
      
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern void Test_BasicDataArr(int[] arr1, int arr1Len, float[] arr2, int arr2Len);
      
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern IntPtr Test_BasicDataRet();
      
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern IntPtr Test_BasicDataRet1();
      
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern void FreeFloatArray(IntPtr arr);
      
          static void Main()
          {
      
              int[] intArr = new int[5] { 1, 2, 3, 4, 5 };
              float[] floatArr = new float[5] { 11f, 22f, 33f, 44f, 55f };
      
              // 調(diào)用傳數(shù)組函數(shù),需同時(shí)傳長(zhǎng)度
              Test_BasicDataArr(intArr, intArr.Length, floatArr, floatArr.Length);
      
              // 調(diào)用返回?cái)?shù)組函數(shù),假設(shè)返回5個(gè)整數(shù),C++ 返回靜態(tài)數(shù)組指針,C#不需要釋放
              IntPtr retPtr = Test_BasicDataRet();
              int[] retArr = new int[5];
              Marshal.Copy(retPtr, retArr, 0, 5);
              Console.WriteLine("Returned array from C++:");
              foreach (var v in retArr)
                  Console.WriteLine(v);
      
              // 調(diào)用返回?cái)?shù)組函數(shù),假設(shè)返回5個(gè)浮點(diǎn)數(shù),C++ 返回堆內(nèi)存指針,C#需要調(diào)用釋放函數(shù)釋放
              IntPtr retFloatPtr = Test_BasicDataRet1();
              float[] retFloatArr = new float[5];
              Marshal.Copy(retFloatPtr, retFloatArr, 0, 5);
              FreeFloatArray(retFloatPtr); // 釋放堆上的數(shù)組
              foreach (var v in retFloatArr)
                  Console.WriteLine(v);
          }
      }
      // ============== C++ 代碼 ==============
      
      #include <iostream>
      #include <cstring>
      
      extern "C" __declspec(dllexport)
      void Test_BasicDataArr(int* arr1, int arr1Len, float* arr2, int arr2Len)
      {
          std::cout << "Received int array from C#: ";
          for (int i = 0; i < arr1Len; i++)
              std::cout << arr1[i] << " ";
          std::cout << std::endl;
      
          std::cout << "Received float array C#: ";
          for (int i = 0; i < arr2Len; i++)
              std::cout << arr2[i] << " ";
          std::cout << std::endl;
      }
      
      static int retArr[5] = { 100, 200, 300, 400, 500 };
      
      extern "C" __declspec(dllexport)
      int* Test_BasicDataRet()
      {
          return retArr;
      }
      
      extern "C" __declspec(dllexport)
      float* Test_BasicDataRet1()
      {
          float* retArr1 = new float[5] { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f };
          return retArr1;
      }
      
      extern "C" __declspec(dllexport)
      void FreeFloatArray(float* arr)
      {
          delete[] arr;
      }

      4.3 字符串傳遞

      • 使用 string 直接傳遞給 const char*,會(huì)自動(dòng)在字符串末尾添加 \0(null 終止符),C++ 端可以直接用 printf 輸出。默認(rèn)編碼是 ANSI,如需傳中文建議使用 UTF-8 編碼,并確保 C++ 控制臺(tái)設(shè)置正確編碼頁(yè)。

      • 使用 UTF-8 編碼的 byte[],需要手動(dòng)在 C# 末尾添加一個(gè) 0 字節(jié)。C++ 依然用 const char* 接收,配合 SetConsoleOutputCP(CP_UTF8) 可正確打印中文。推薦用于跨平臺(tái)、支持中文、傳遞原始字符串?dāng)?shù)據(jù)等場(chǎng)景。

      示例

      // ============== C# 代碼 ==============
      using System.Runtime.InteropServices;
      class Program
      {
          // C++ 接收字符串(以 null 結(jié)尾的 ANSI 字符串)
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern void Test_BasicDataString(string str);
      
          // C++ 接收字節(jié)數(shù)組(需要自己確保字節(jié)數(shù)組以 \0 結(jié)尾)
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern void Test_BasicDataByteArr(byte[] str);
      
          static void Main()
          {
              string str = "你好";
      
              // 方法1:直接傳遞 string,DllImport 自動(dòng)轉(zhuǎn)換為 null 結(jié)尾的 ANSI 字符串
              Test_BasicDataString(str);
      
              // 方法2:手動(dòng)將字符串轉(zhuǎn)換成 UTF-8 字節(jié)數(shù)組(不含尾部 \0),字節(jié)數(shù)組傳遞時(shí),自己加上 \0 結(jié)束符
              byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(str);
              byte[] utf8BytesWithNull = utf8Bytes.Concat(new byte[] { 0 }).ToArray();
              Test_BasicDataByteArr(utf8BytesWithNull);
      
              Console.ReadLine();
          }
      }
      

      4.4 結(jié)構(gòu)體傳遞

      方法一:手動(dòng)偏移

      通過(guò)已知偏移,使用 Marshal.ReadInt32ReadInt64Marshal.Copy 等方法逐字段讀取結(jié)構(gòu)體內(nèi)容。

      // ============== C++ 代碼 ==============
      #include <string.h>
      struct FrameInfo
      {
      	char username[20];	//0-20
      	double pts;			//24-32
      };
      
      struct Frame
      {
      	int width;				//0-4
      	int height;				//4-8
      	int format;				//8-12
      	int linesize[4];		//12-28
      	unsigned char* data[4];	//32-64  指針大小8,需要是8的倍數(shù)
      	FrameInfo* info;		//64-72  指針大小8
      };
      Frame frame;
      FrameInfo info;
      extern "C" __declspec(dllexport) Frame* Test_Struct()
      {
      
      	frame.width = 1920;
      	frame.height = 1080;
      	frame.format = 1; 
      	for (size_t i = 0; i < 4; i++)
      	{
      		frame.linesize[i] = 100 * i;
      		frame.data[i] = new unsigned char[10];
      		for (size_t j = 0; j < 10; j++)
      		{
      			frame.data[i][j] = i;
      		}
      	}
      	info.pts = 12.5;
      	memset(info.username, 0, 20);
      	memcpy(info.username, "hello world", strlen("hello world"));
      	frame.info = &info;
      	return &frame;
      }
      
      // ============== C# 代碼 ==============
      using System;
      using System.Runtime.InteropServices;
      
      class Program
      {
          // 聲明導(dǎo)入的本地方法,返回一個(gè)指向 Frame 結(jié)構(gòu)體的指針
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern IntPtr Test_Struct();
      
          static void Main()
          {
              // 調(diào)用本地方法,獲取 Frame 結(jié)構(gòu)體指針
              IntPtr ptr = Test_Struct();
      
              // 讀取 Frame 結(jié)構(gòu)體前3個(gè)int成員,偏移分別是0, 4, 8
              int width = Marshal.ReadInt32(ptr, 0);   // 讀取 width
              int height = Marshal.ReadInt32(ptr, 4);  // 讀取 height
              int format = Marshal.ReadInt32(ptr, 8);  // 讀取 format
      
              // 創(chuàng)建整型數(shù)組接收 linesize[4],占16字節(jié)(4個(gè)int)
              int[] linesize = new int[4];
              // linesize數(shù)組在結(jié)構(gòu)體偏移12處
              IntPtr linesizePtr = IntPtr.Add(ptr, 12);
              // 從非托管內(nèi)存復(fù)制4個(gè)int到托管linesize數(shù)組
              Marshal.Copy(linesizePtr, linesize, 0, 4);
      
              // 創(chuàng)建IntPtr數(shù)組用于存放 data[4](4個(gè)指針)
              IntPtr[] datas = new IntPtr[4];
              // data數(shù)組在結(jié)構(gòu)體中偏移為12+16+4=32
              IntPtr dataPtr = IntPtr.Add(ptr, 32);
              // 從非托管內(nèi)存復(fù)制4個(gè)指針到datas數(shù)組
              Marshal.Copy(dataPtr, datas, 0, 4);
      
              // 遍歷4個(gè)指針,從每個(gè)地址拷貝10字節(jié)數(shù)據(jù)到托管byte數(shù)組
              for (int i = 0; i < 4; i++)
              {
                  byte[] temp = new byte[10]; // 臨時(shí)數(shù)組接收數(shù)據(jù)
                  Marshal.Copy(datas[i], temp, 0, 10);
                  // 這里可以對(duì)temp數(shù)組做后續(xù)處理
              }
      
              // 讀取 Frame 結(jié)構(gòu)體中 info 指針,偏移64處
              IntPtr infoPtr = Marshal.ReadIntPtr(ptr, 64);
      
              // 讀取 info 結(jié)構(gòu)體中 username 字符數(shù)組(20字節(jié))
              byte[] username = new byte[20];
              Marshal.Copy(infoPtr, username, 0, 20);
      
              // 讀取 info 結(jié)構(gòu)體中 double pts,偏移24字節(jié)(20字節(jié)username + 4字節(jié)padding)
              // 先讀64位整數(shù),再轉(zhuǎn)換成double
              double pts = BitConverter.Int64BitsToDouble(Marshal.ReadInt64(infoPtr, 24));
      
              // 保持控制臺(tái)窗口,方便查看輸出
              Console.ReadLine();
          }

      方法二:結(jié)構(gòu)體映射

      在 C# 中使用 [StructLayout] 正確定義結(jié)構(gòu)體布局,調(diào)用 Marshal.PtrToStructure<T> 一次性將內(nèi)存映射為結(jié)構(gòu)體對(duì)象。

      // ============== C# 代碼 ==============
      using System;
      using System.Runtime.InteropServices;
      
      [StructLayout(LayoutKind.Sequential)]
      struct FrameInfo
      {
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
          public byte[] username;
      
          public double pts;
      }
      
      [StructLayout(LayoutKind.Sequential)]
      struct Frame
      {
          public int width;
          public int height;
          public int format;
      
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
          public int[] linesize;
      
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
          public IntPtr[] data;
      
          public IntPtr info;
      }
      class Program
      {
          // 聲明導(dǎo)入的本地方法,返回一個(gè)指向 Frame 結(jié)構(gòu)體的指針
          [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
          public static extern IntPtr Test_Struct();
      
          static void Main()
          {
              // 調(diào)用本地方法,獲取 Frame 結(jié)構(gòu)體指針
              IntPtr ptr = Test_Struct();
      
              Frame frame = Marshal.PtrToStructure<Frame>(ptr);
              FrameInfo info = Marshal.PtrToStructure<FrameInfo>(frame.info);
              Console.WriteLine(info.pts);
          }
      }

      ?? 注意點(diǎn):定長(zhǎng)數(shù)組必須使用 [MarshalAs(ByValArray)] 顯式標(biāo)注

      在進(jìn)行 C++ 與 C# 的結(jié)構(gòu)體互操作時(shí),C++ 中的定長(zhǎng)數(shù)組(如 char name[20])不能直接在 C# 中用數(shù)組表示,必須使用 [MarshalAs(UnmanagedType.ByValArray)] 顯式標(biāo)注,否則會(huì)導(dǎo)致內(nèi)存布局不一致或運(yùn)行時(shí)錯(cuò)誤。

      ?? 注意點(diǎn):結(jié)構(gòu)體使用 bool 字段時(shí)必須謹(jǐn)慎,尤其在有 Pack 設(shè)置時(shí)!

      //=======================? C++ 結(jié)構(gòu)體=======================
      
      // 編譯器默認(rèn)對(duì)齊,通常是 4 或 8 字節(jié)
      struct MyStruct
      {
          bool flag1;   // 0-1
          bool flag2;   // 1-2
          int value;    // 4-8
      };
      
      //=========================? C# 結(jié)構(gòu)體=========================
      // C# 結(jié)構(gòu)體(默認(rèn)布局)
      struct MyStruct {
          public bool flag1;//0-4
          public bool flag2;//4-8
          public int value; //8-12
      }
      
      //C# 結(jié)構(gòu)體和 C++ 保持一致
      struct BoolStruct
      {
          [MarshalAs(UnmanagedType.U1)]
          public bool flag1;  // 1 字節(jié)
      
          [MarshalAs(UnmanagedType.U1)]
          public bool flag2;  // 1 字節(jié)
      
          public int value;   // 按 4 字節(jié)對(duì)齊,offset 4
      }
      

        

        

        

      posted @ 2025-06-09 09:34  灣仔碼農(nóng)  閱讀(122)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲春色在线视频| 在线a级毛片无码免费真人| 亚洲欧美日韩综合一区二区| 国产精品亚洲二区在线播放| 欧美性受xxxx黑人猛交| 蜜臀av一区二区三区在线| 日韩免费视频一一二区| 日韩精品人妻av一区二区三区| 国产精品线在线精品| 欧美精品V欧洲精品| 综合色在线| 看全色黄大黄大色免费久久| 久久夜色精品国产亚洲a| 日韩乱码人妻无码中文字幕视频| 国产成人av免费观看| 3d全彩无码啪啪本子全彩| 亚洲AV天天做在线观看| 中文字幕人妻中出制服诱惑| 亚洲日本精品一区二区| 冷水江市| 麻豆蜜桃av蜜臀av色欲av| 免费无码黄十八禁网站| 国产精品无码专区av在线播放| 岛国中文字幕一区二区| 全部免费毛片在线播放| 国产精品国产三级国产试看| 久99久热只有精品国产99| 国产av不卡一区二区| 国产乱子伦无套一区二区三区 | 色综合久久精品亚洲国产| 姐姐6电视剧在线观看| 国偷自产一区二区三区在线视频 | 四虎亚洲精品高清在线观看| 精品国产精品午夜福利| 国产三级精品三级在线观看| 伊人久久大香线蕉aⅴ色| 人妻系列无码专区69影院| 国产精品偷乱一区二区三区| 一本大道久久香蕉成人网| 999国产精品999久久久久久| 国产成人一区二区三区免费|