VB、C#、VC使用条件编译自动选择结构体对齐方式

VB、C#、VC使用条件编译使程序自动选择结构体对齐方式


一、系统默认内存对齐

1、Windows 64 位系统默认 8 字节,Windows 32 位系统默认 4 字节

2、Linux 64 位系统默认 8 字节,Linux 32 位系统默认 4 字节


二、常用程序默认对齐

1、Office 64 位程序默认 8 字节,Office 32 系统默认 4 字节(VBA 结构体编程才能体会)

2、Visual Studio 2017 默认 8 字节(VB、C#、VC 都是默认 8 字节),VC2017 可以选择结构体对齐(1、2、4、8、16)

3、Visual Studio 6.0 默认 4 字节,VC6.0 可以选择结构体对齐(1、2、4、8、16)


三、使用条件编译自动选择结构体对齐方式

根据内存发展的规则,32 位系统默认 4 字节对齐,64 位系统默认 8 字节对齐,那么采用VS编程就可以使用条件编译程序。

以 VB.net 2017 为例,在项目属性里,高级编译选项,设置定义 TRACE 常数:

1、选择项目 x64 平台,自定义常量 x64 = True

VB、C#、VC使用条件编译自动选择结构体对齐方式_第1张图片

或者,选择项目 x86 平台,自定义常量 x86 = True

VB、C#、VC使用条件编译自动选择结构体对齐方式_第2张图片

2、编辑条件编译程序代码

VB.NET 代码:
#If x86 Then   '编译是 x86 平台,按 4 字节结构体参数  '条件编译语句,根据选择的编译平台,选择结构体的对齐方式
    ''' 椭球转换参数 
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=4)>'编译为X86,采用Pack=4。编译为X64,Pack=8或默认。
    Public Structure SevenParam
        Dim dX As Double 'X平移
        Dim dY As Double 'Y平移
        Dim dZ As Double 'Z平移
        Dim rX As Double 'X旋转
        Dim rY As Double 'Y旋转
        Dim rZ As Double 'Z旋转
        Dim K As Double '尺度
    End Structure
    ''' 定义椭球投影参数   
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=4)>   '编译为X86,采用Pack=4。编译为X64,Pack=8或默认。
    Public Structure ProjectionParam
        ''' 中央子午线
        Dim CentralMeridian As Double
        ''' 是否采用自动计算中央子午线或输入中央子午线的布尔值
        Dim CentBool As Boolean
        ''' 投影尺度
        Dim ProjectionScale As Double
        ''' 是否自动椭球参数的布尔值
        Dim eTwoBool As Boolean
        ''' 北向常数
        Dim NorthwardConstant As Double
        ''' 是否北向或南向坐标的布尔值
        Dim NortBool As Boolean
        ''' 东向常数
        Dim EasterlyConstant As Double
        ''' 是否东向或西向坐标的布尔值
        Dim EastBool As Boolean
    End Structure
#Else    '编译不是 x86 平台,按 8 字节结构体参数
    ''' 椭球转换七参数 
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=8)>'编译为X86,采用Pack=4。编译为X64,Pack=8或默认。
    Public Structure SevenParam
        Dim dX As Double 'X平移
        Dim dY As Double 'Y平移
        Dim dZ As Double 'Z平移
        Dim rX As Double 'X旋转
        Dim rY As Double 'Y旋转
        Dim rZ As Double 'Z旋转
        Dim K As Double '尺度
    End Structure
    ''' 定义椭球投影参数   
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=8)>   '编译为X86,采用Pack=4。编译为X64,Pack=8或默认。
    Public Structure ProjectionParam
        ''' 中央子午线
        Dim CentralMeridian As Double
        ''' 是否采用自动计算中央子午线或输入中央子午线的布尔值
        Dim CentBool As Boolean
        ''' 投影尺度
        Dim ProjectionScale As Double
        ''' 是否自动椭球参数的布尔值
        Dim eTwoBool As Boolean
        ''' 北向常数
        Dim NorthwardConstant As Double
        ''' 是否北向或南向坐标的布尔值
        Dim NortBool As Boolean
        ''' 东向常数
        Dim EasterlyConstant As Double
        ''' 是否东向或西向坐标的布尔值
        Dim EastBool As Boolean
    End Structure
#End If
C# 代码与 VB.NET 类同
先设置高级编译选项的自定义常数,然后编辑如下代码:
#if x86 //编译是 x86 平台,按 4 字节结构体参数 '条件编译语句,根据选择的编译平台,选择结构体的对齐方式
	/// 椭球转换参数 
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=4)]
	public struct SevenParam
	{
		public double dX; //X平移
		public double dY; //Y平移
		public double dZ; //Z平移
		public double rX; //X旋转
		public double rY; //Y旋转
		public double rZ; //Z旋转
		public double K; //尺度
	}
	/// 定义椭球投影参数   
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=4)]
	public struct ProjectionParam
	{
		/// 中央子午线
		public double CentralMeridian;
		/// 是否采用自动计算中央子午线或输入中央子午线的布尔值
		public bool CentBool;
		/// 投影尺度
		public double ProjectionScale;
		/// 是否自动椭球参数的布尔值
		public bool eTwoBool;
		/// 北向常数
		public double NorthwardConstant;
		/// 是否北向或南向坐标的布尔值
		public bool NortBool;
		/// 东向常数
		public double EasterlyConstant;
		/// 是否东向或西向坐标的布尔值
		public bool EastBool;
	}
#else //编译不是 x86 平台,按 8 字节结构体参数
	/// 椭球转换七参数 
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=8)]
	public struct SevenParam
	{
		public double dX; //X平移
		public double dY; //Y平移
		public double dZ; //Z平移
		public double rX; //X旋转
		public double rY; //Y旋转
		public double rZ; //Z旋转
		public double K; //尺度
	}
	/// 定义椭球投影参数   
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=8)]
	public struct ProjectionParam
	{
		/// 中央子午线
		public double CentralMeridian;
		/// 是否采用自动计算中央子午线或输入中央子午线的布尔值
		public bool CentBool;
		/// 投影尺度
		public double ProjectionScale;
		/// 是否自动椭球参数的布尔值
		public bool eTwoBool;
		/// 北向常数
		public double NorthwardConstant;
		/// 是否北向或南向坐标的布尔值
		public bool NortBool;
		/// 东向常数
		public double EasterlyConstant;
		/// 是否东向或西向坐标的布尔值
		public bool EastBool;
	}
#endif

VC++ 可以直接进入项目属性,C/C++ 的代码生成里,设置结构成员对齐,x64 设置为 8 字节,x86 设置为 4 字节,如图

VB、C#、VC使用条件编译自动选择结构体对齐方式_第3张图片
VB、C#、VC使用条件编译自动选择结构体对齐方式_第4张图片

也可以具体编辑需要设置对齐的代码:
#ifdef _M_IX86 //编译是 x86 平台,按 4 字节结构体参数 '条件编译语句,根据选择的编译平台,选择结构体的对齐方式(或 _WIN32)
	/// 椭球转换参数 
    #pragma pack(4)/4字节对齐
	public struct SevenParam
	{
		public double dX; //X平移
		public double dY; //Y平移
		public double dZ; //Z平移
		public double rX; //X旋转
		public double rY; //Y旋转
		public double rZ; //Z旋转
		public double K; //尺度
	}
	/// 定义椭球投影参数   
	public struct ProjectionParam
	{
		/// 中央子午线
		public double CentralMeridian;
		/// 是否采用自动计算中央子午线或输入中央子午线的布尔值
		public bool CentBool;
		/// 投影尺度
		public double ProjectionScale;
		/// 是否自动椭球参数的布尔值
		public bool eTwoBool;
		/// 北向常数
		public double NorthwardConstant;
		/// 是否北向或南向坐标的布尔值
		public bool NortBool;
		/// 东向常数
		public double EasterlyConstant;
		/// 是否东向或西向坐标的布尔值
		public bool EastBool;
	}
	#pragma pack()//恢复默认对齐
	
#else // _M_X64 //编译不是 x86 平台,按 8 字节结构体参数 (或 _WIN64)
	/// 椭球转换七参数 
    #pragma pack(8)//按8字节对齐
	public struct SevenParam
	{
		public double dX; //X平移
		public double dY; //Y平移
		public double dZ; //Z平移
		public double rX; //X旋转
		public double rY; //Y旋转
		public double rZ; //Z旋转
		public double K; //尺度
	}
	/// 定义椭球投影参数   
	public struct ProjectionParam
	{
		/// 中央子午线
		public double CentralMeridian;
		/// 是否采用自动计算中央子午线或输入中央子午线的布尔值
		public bool CentBool;
		/// 投影尺度
		public double ProjectionScale;
		/// 是否自动椭球参数的布尔值
		public bool eTwoBool;
		/// 北向常数
		public double NorthwardConstant;
		/// 是否北向或南向坐标的布尔值
		public bool NortBool;
		/// 东向常数
		public double EasterlyConstant;
		/// 是否东向或西向坐标的布尔值
		public bool EastBool;
	}
	#pragma pack()//恢复默认对齐
#endif

你可能感兴趣的:(VC++2017,VB,C#,VC++条件编译,C#条件编译,VB.NET条件编译,条件编译选择结构体对齐)