在c#中声明一个指向dll中非托管结构的指针

本文关键字:dll 结构 指针 一个 声明 | 更新日期: 2023-09-27 18:10:16

我被一个问题困住了,我已经两天没能解决了。

错误信息如下:

不能获取托管类型的地址、大小或声明指向托管类型的指针("Control_Vertilon.Imports.PHOTONIQ_CONFIG_TABLE")

下面是代码

         UInt16[] Arguments = new UInt16[PHOTONIQ_ARG_BUFF_SZ];
         PHOTONIQ_CONFIG_TABLE PhotoniqConfigTable = new PHOTONIQ_CONFIG_TABLE();
        UInt16 *cfgPtr = (UInt16*)&PhotoniqConfigTable;       
        for(int i = 0; i < Imports.CONFIG_TABLE_SZ; i++){
            Arguments[i+1] =  *cfgPtr++; 
        }
        Imports.ControlInterface(Opcode, Arguments, 0x1, Imports.TimeoutMs, ref errInNoErrorStruct, ref NumRetArguments, ref PhotoniqConfigTable, Imports.CONFIG_TABLE_SZ, ref errOutStruct);   

我编组的PhotoniqConfigTable如下所示,

       [StructLayout(LayoutKind.Sequential)]
        unsafe public struct PHOTONIQ_CONFIG_TABLE
        {
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SystemMode;       //Indicates current system mode, acquire or standby mode 0 = Standby Mode 1 = Acquire Mode
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVLimit0;   // Maximum allowed voltage on HV supply 1 Range = 500 ?9250 (50 ?925V)
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVLimit1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 NumChannelsB0;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 NumChannelsB1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 NumChannelsB2;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 NumChannelsB3;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVEnabled;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVSetpoint0;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVSetpoint1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 UserConfigID;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 DCRD_AOut_0;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 BandEnables;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band0StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band0StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band1StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band1StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band2StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band2StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band3StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band3StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band4StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band4StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band5StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band5StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band6StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band6StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band7StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band7StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 FlagEnables;      // pterm flag enables
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] Flag0Operands;  // flag 0 operands: 64 bits
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] Flag1Operands;  // flag 0 operands: 64 bits
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] Flag2Operands;  // flag 0 operands: 64 bits
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] Flag3Operands;  // flag 0 operands: 64 bits
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] Flag4Operands;  // flag 0 operands: 64 bits
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] Flag5Operands;  // flag 0 operands: 64 bits
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] Flag6Operands;  // flag 0 operands: 64 bits
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] Flag7Operands;  // flag 0 operands: 64 bits
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm0;               // flag 0 - 7 product terms
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm2;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm3;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm4;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm5;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm6;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm7;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 DataFilterEnable; // 1 = enable spectral filtering, 0 = disable
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 ProcessingEnables;    // bit 0 = spect filt, bit 1 = gain, 2 = bkgnd sub.
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 TimestampEnable;  // 1 = enable time stamp, 0 = disable
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 DACspare;
            [MarshalAs(UnmanagedType.I4)]
            public Int32 TimestampInterval; //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 CustomWordsEnable;    // 1/0
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 EventCustomCount; //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 RESERVED;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 ImageAcqMode;     // 1 = image, 0 = particle
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 InputTrigThresh;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 InputTrigChannel; // 
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 RangeErrorEnable; // 1 = enable range error, 0 = disable
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 CrossBankConfig;  //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 ReportPackingMode;    //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 GPOutputEnable;       //
            [MarshalAs(UnmanagedType.I4)]
            public Int32 GPOutputDelay;     //
            [MarshalAs(UnmanagedType.I4)]
            public Int32 GPOutputPeriod;        //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 IntBoxcarEnable;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 BoxcarWidthEnable;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public Int32[] ResetDelay;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] TrigSource;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public Int32[] TrigPeriod;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public Int32[] IntegPeriod;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public Int32[] IntegDelay;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel0;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel2;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel3;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel4;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel5;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel6;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel7;
            [MarshalAs(UnmanagedType.I4)]
            public Int32 TriggerEndCount;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 TrigStampSelect;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public UInt16[] DataFormat;     // 4 banks: 0 = 17bit sign/mag, 1 = 16bit 2's, comp, 2 = 16b, 2's 1/2 scale
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 7)]
            public UInt16[] RESERVED1;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256)]
            public UInt16[] GainArray;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256)]
            public UInt16[] TrigThreshArray;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 16)]
            public UInt16[] TrigEnableArray;    // 256 bits, 1/0 for each channel (max of 256 channels)
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 322)]
            public UInt16[] RESERVED2;          //  678-999
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 250)]
            public UInt16[] CustomArray;            // user custom space: 1000-1249
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 567)]
            public UInt16[] FactoryArray;           // start of factory table
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32)]
            public SByte[] ModelNumber;         // model number
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 151)]
            public UInt16[] FactoryArray1;      // last piece of factory table
        }  

问题是,我认为我使结构非托管类型,但编译器说它是托管类型。

或者可能是UInt16指针在托管代码中指向这种方式是错误的。

缓冲区参数[]是在16位,这是在dll函数传递参数,所以我坚持使用16位是否使用指针或缓冲区来移动数据。

如果有人能帮忙解决这个问题,那将是极大的帮助。

我已经在网上搜索了,但没有找到确切的答案。

提前感谢。

==================================================================================

你好,谢谢你的回复,

这里我收到不同的错误代码如下:

        fixed (UInt16 *cfgPtr = (UInt16*)&PhotoniqConfigTable){
            //modify config table, then send it back up to PhotoniQ
            PhotoniqConfigTable.NumChannelsB0 = 6;
            PhotoniqConfigTable.IntegPeriod[0] = per;
            PhotoniqConfigTable.TrigPeriod[0] = 100000;
            PhotoniqConfigTable.TrigStampSelect = 1;
            PhotoniqConfigTable.TimestampEnable = 0;
            PhotoniqConfigTable.RangeErrorEnable = 0;
            PhotoniqConfigTable.DataFormat[0] = 0;
            PhotoniqConfigTable.GPOutputEnable = 1;
            PhotoniqConfigTable.GPOutputDelay = 10;
            PhotoniqConfigTable.GPOutputPeriod = 1000;
            for (int i = 0; i < Imports.CONFIG_TABLE_SZ; i++)
            {
                Arguments[i + 1] = *cfgPtr++;
            }
        }      

错误信息是:

不能赋值给'cfgPtr',因为它是'固定变量'。

固定语句赋值的右边不能是强制转换表达式

不能使用包含在非固定表达式中的固定大小缓冲区。尝试使用固定语句。(三行相同错误)

我时间不够,谁能给我解释一下就太好了。

结构现在看起来如下:

        [StructLayout(LayoutKind.Sequential)]
        unsafe public struct PHOTONIQ_CONFIG_TABLE
        {
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SystemMode;       //Indicates current system mode, acquire or standby mode 0 = Standby Mode 1 = Acquire Mode
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVLimit0;   // Maximum allowed voltage on HV supply 1 Range = 500 ?9250 (50 ?925V)
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVLimit1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 NumChannelsB0;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 NumChannelsB1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 NumChannelsB2;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 NumChannelsB3;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVEnabled;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVSetpoint0;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 HVSetpoint1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 UserConfigID;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 DCRD_AOut_0;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 BandEnables;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band0StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band0StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band1StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band1StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band2StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band2StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band3StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band3StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band4StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band4StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band5StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band5StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band6StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band6StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band7StartIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 Band7StopIndex;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 FlagEnables;      // pterm flag enables
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 Flag0Operands[4];   // flag 0 operands: 64 bits
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 Flag1Operands[4];   // flag 0 operands: 64 bits
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 Flag2Operands[4];   // flag 0 operands: 64 bits
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 Flag3Operands[4];   // flag 0 operands: 64 bits
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 Flag4Operands[4];   // flag 0 operands: 64 bits
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 Flag5Operands[4];   // flag 0 operands: 64 bits
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 Flag6Operands[4];   // flag 0 operands: 64 bits
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 Flag7Operands[4];   // flag 0 operands: 64 bits
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm0;               // flag 0 - 7 product terms
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm2;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm3;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm4;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm5;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm6;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 PTerm7;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 DataFilterEnable; // 1 = enable spectral filtering, 0 = disable
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 ProcessingEnables;    // bit 0 = spect filt, bit 1 = gain, 2 = bkgnd sub.
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 TimestampEnable;  // 1 = enable time stamp, 0 = disable
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 DACspare;
            [MarshalAs(UnmanagedType.I4)]
            public Int32 TimestampInterval; //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 CustomWordsEnable;    // 1/0
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 EventCustomCount; //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 RESERVED;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 ImageAcqMode;     // 1 = image, 0 = particle
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 InputTrigThresh;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 InputTrigChannel; // 
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 RangeErrorEnable; // 1 = enable range error, 0 = disable
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 CrossBankConfig;  //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 ReportPackingMode;    //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 GPOutputEnable;       //
            [MarshalAs(UnmanagedType.I4)]
            public Int32 GPOutputDelay;     //
            [MarshalAs(UnmanagedType.I4)]
            public Int32 GPOutputPeriod;        //
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 IntBoxcarEnable;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 BoxcarWidthEnable;
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed Int32 ResetDelay[4];
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 TrigSource[4];
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed Int32 TrigPeriod[4];
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed Int32 IntegPeriod[4];
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed Int32 IntegDelay[4];
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel0;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel1;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel2;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel3;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel4;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel5;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel6;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 SibSel7;
            [MarshalAs(UnmanagedType.I4)]
            public Int32 TriggerEndCount;
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 TrigStampSelect;
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
            public fixed UInt16 DataFormat[4];      // 4 banks: 0 = 17bit sign/mag, 1 = 16bit 2's, comp, 2 = 16b, 2's 1/2 scale
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 7)]
            public fixed UInt16 RESERVED1[7];
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256)]
            public fixed UInt16 GainArray[256];
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256)]
            public fixed UInt16 TrigThreshArray[256];
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 16)]
            public fixed UInt16 TrigEnableArray[16];    // 256 bits, 1/0 for each channel (max of 256 channels)
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 322)]
            public fixed UInt16 RESERVED2[322];         //  678-999
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 250)]
            public fixed UInt16 CustomArray[250];           // user custom space: 1000-1249
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 567)]
            public fixed UInt16 FactoryArray[567];          // start of factory table
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32)]
            public fixed SByte ModelNumber[32];         // model number
            //[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 151)]
            public fixed UInt16 FactoryArray1[151];
            //public fixed UInt16 FactoryArray1[151];       // last piece of factory table
        };  

在c#中声明一个指向dll中非托管结构的指针

第二个答案,回答你的第二个问题:

错误信息是:

Cannot assign to 'cfgPtr' because it is a 'fixed variable'.
The right hand side of a fixed statement assignment may not be a cast expression.
You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement. 

错误信息告诉你哪里出错了。阅读。

不能赋值给'cfgPtr',因为它是'固定变量'。

你在这里给它赋值:

Arguments[i + 1] = *cfgPtr++;

一旦初始化了包含指向空间固定块的指针的变量,就不能更改该变量,因为可能会将其更改为指向非空间固定块。为了防止这种常见的错误,c#会阻止您修改该变量。

如果你想修改变量,创建一个不同的变量来代替。将其设置为cfgPtr,然后修改变量。确保你做得正确;现在,您有责任确保指针始终指向固定的对象。

The right hand side of a fixed statement assignment may not be a cast expression.

在我的上一个回答中,我告诉您阅读规范的第18.7节,其中指出"fixed"语句需要:

引用可移动变量的固定大小缓冲区成员的简单名称或成员访问

强制转换表达式不是"简单的名称或成员访问"。强制转换表达式就是强制转换表达式。这个演员阵容根本就不合理!指向结构体的指针不是指向ushort的指针!

移除石膏。将初始化式中的表达式更改为访问可移动变量的固定大小缓冲区成员的成员。

You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement.

你直接使用了一个固定大小的缓冲区。你不能这么做。只能通过获取指向它的指针来使用固定大小的缓冲区。同样,这是安全系统的一部分,可确保您不会意外访问非固定位置的固定大小缓冲区。停止尝试直接访问缓冲区。获取一个指向缓冲区的指针,并通过该指针访问它。

我时间不够,谁能给我解释一下就太好了。

让我在这一点上非常清楚:你已经关闭了托管安全系统,你的程序的正确性和进程的稳定性现在是你的问题,而不是托管运行时的问题。如果你不理解关于如何安全管理你自己的指针的一切停止你正在做的事情并阅读它,直到你完全理解它。现在匆忙地编写一大堆你不理解的代码,你就有可能在以后处理可怕的bug。现在不是着急的时候。

从阅读第18章开始。只有彻底理解了所有这些内容,才可以尝试编写复杂的不安全代码。

您已经说过如何在非托管内存中布局数组,但还没有说如何在托管内存中布局数组。因此,编译器认为在该结构体中有一堆对垃圾收集的托管内存的引用——所有这些数组——并且不允许您将指向它的指针作为结果。

我怀疑你打算这些数组是固定大小的缓冲区,而不是托管数组,是吗?

您需要阅读c#规范,第18.7节,以了解固定大小的缓冲区如何在结构体中工作。

还需要注意的是,"固定大小"数组和指针指向的"固定位置"对象之间有很大的区别;这是fixed的两种完全不同的用法。许多人把它们弄混了,特别是因为要正确和安全地使用"大小固定"的缓冲区,缓冲区的内存必须"固定在适当的位置"。

代替

        [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 151)]
        public UInt16[] FactoryArray1;

        public unsafe fixed ushort FactoryArray1[151];

因为数组在托管和非托管内存中"看起来"不同,但固定大小的缓冲区"看起来"相同(即是位元化的)。