系统.AccessViolationException:试图读写受保护的内存

本文关键字:受保护 内存 读写 AccessViolationException 系统 | 更新日期: 2023-09-27 17:50:23

我有一个关于从c++非托管库开始生产c#包装器的问题。每次我陷入一个系统。AccessViolationException:试图读写受保护的内存。我知道这可能取决于我将结构及其元素从c++转换为c#的方式,但我不知道如何解决。有人能帮帮我吗?

c++代码:

typedef struct VBLEnvironmentVariable_t
{
VBLObjectHeader mHeader;                     
DWORD           mNameLength;                 
DWORD           mDataLength;                 
LPSTR           mName;                       
LPBYTE          mData;                       
} VBLEnvironmentVariable;
typedef struct VBLAppTrigger_t
{
VBLObjectHeader mHeader;                     
ULONGLONG       mPreTriggerTime;             
ULONGLONG       mPostTriggerTime;            
WORD            mChannel;                    
WORD            mFlags;                      
DWORD           mAppSecific2;                
} VBLAppTrigger;
//signature
BLAPI( BOOL)   BLWriteObject( HANDLE hFile, VBLObjectHeaderBase* pBase);

//how function is called
int write_test( LPCTSTR pFileName, LPDWORD pWritten)
{
if ( NULL == pWritten)
{
    return -1;
}
*pWritten = 0;
/* open file */
hFile = BLCreateFile( pFileName, GENERIC_WRITE);
if ( INVALID_HANDLE_VALUE == hFile)
{
    return -1;
}
/* set applicaton information */
/* bSuccess = BLSetApplication( hFile, BL_APPID_UNKNOWN, 1, 0, 0); */
bSuccess = BLSetApplication( hFile, BL_APPID_CANCASEXLLOG, 1, 0, 1);
GetSystemTime( &systemTime);
bSuccess = bSuccess && BLSetMeasurementStartTime( hFile, &systemTime);
/* set write options */
bSuccess = bSuccess && BLSetWriteOptions( hFile, 6, 0);

if ( bSuccess)
{
    // setup object headers 
    appTrigger.mHeader.mBase.mSignature = BL_OBJ_SIGNATURE;
    appTrigger.mHeader.mBase.mHeaderSize = sizeof( appTrigger.mHeader);
    appTrigger.mHeader.mBase.mHeaderVersion = 1;
    appTrigger.mHeader.mBase.mObjectSize = sizeof( VBLAppTrigger);
    appTrigger.mHeader.mBase.mObjectType = BL_OBJ_TYPE_APP_TRIGGER;
    appTrigger.mHeader.mObjectFlags = BL_OBJ_FLAG_TIME_ONE_NANS;
    message.mHeader.mBase.mSignature = BL_OBJ_SIGNATURE;
    message.mHeader.mBase.mHeaderSize = sizeof( message.mHeader);
    message.mHeader.mBase.mHeaderVersion = 1;
    message.mHeader.mBase.mObjectSize = sizeof( VBLCANMessage);
    message.mHeader.mBase.mObjectType = BL_OBJ_TYPE_CAN_MESSAGE;
    message.mHeader.mObjectFlags = BL_OBJ_FLAG_TIME_ONE_NANS;
    variable_s.mHeader.mBase.mSignature = BL_OBJ_SIGNATURE;
    variable_s.mHeader.mBase.mHeaderSize = sizeof( variable_s.mHeader);
    variable_s.mHeader.mBase.mHeaderVersion = 1;
    variable_s.mHeader.mBase.mObjectType = BL_OBJ_TYPE_ENV_STRING;
    variable_s.mHeader.mObjectFlags = BL_OBJ_FLAG_TIME_ONE_NANS;
    variable_i.mHeader.mBase.mSignature = BL_OBJ_SIGNATURE;
    variable_i.mHeader.mBase.mHeaderSize = sizeof( variable_i.mHeader);
    variable_i.mHeader.mBase.mHeaderVersion = 1;
    variable_i.mHeader.mBase.mObjectType = BL_OBJ_TYPE_ENV_INTEGER;
    variable_i.mHeader.mObjectFlags = BL_OBJ_FLAG_TIME_ONE_NANS;
    ethframe.mHeader.mBase.mSignature = BL_OBJ_SIGNATURE;
    ethframe.mHeader.mBase.mHeaderSize = sizeof( ethframe.mHeader);
    ethframe.mHeader.mBase.mHeaderVersion = 1;
    ethframe.mHeader.mBase.mObjectType = BL_OBJ_TYPE_ETHERNET_FRAME;
    ethframe.mHeader.mObjectFlags = BL_OBJ_FLAG_TIME_ONE_NANS;
    appText.mHeader.mBase.mSignature = BL_OBJ_SIGNATURE;
    appText.mHeader.mBase.mHeaderSize = sizeof( appText.mHeader);
    appText.mHeader.mBase.mHeaderVersion = 1;
    appText.mHeader.mBase.mObjectType = BL_OBJ_TYPE_APP_TEXT;
    appText.mHeader.mObjectFlags = BL_OBJ_FLAG_TIME_ONE_NANS;
    for ( i = 0; i < 1000; ++i)
    {
        ethbuffer[i] = ( BYTE)i;
    }
    for ( i = 0; i < 1000 && bSuccess; ++i)
    {
        // increment in milliseconds 
        time = i * 10000000;
        // setup app trigger object header 
        appTrigger.mHeader.mObjectTimeStamp = time;
        // write app trigger object 
        bSuccess = BLWriteObject( hFile, &appTrigger.mHeader.mBase);
        *pWritten += bSuccess ? 1 : 0;
        // setup CAN object header 
        message.mHeader.mObjectTimeStamp = time;
        // setup CAN message 
        message.mChannel = 1;
        message.mFlags = CAN_MSG_FLAGS( 0, 0);
        message.mDLC = 8;
        message.mID = 0x100;
        memcpy( message.mData, ( i % 2) ? _T( "01234567") : _T( "76543210"), message.mDLC);
        // write CAN message 
        bSuccess = BLWriteObject( hFile, &message.mHeader.mBase);
        *pWritten += bSuccess ? 1 : 0;
        if ( 0 == ( i % 3) && bSuccess)
        {
            // setup environment variable object headers 
            variable_s.mHeader.mObjectTimeStamp = time;
            variable_i.mHeader.mObjectTimeStamp = time;
            // setup environment variables 
            variable_s.mNameLength = strlen( ENV_NAME1);
            variable_s.mDataLength = strlen( ( i % 2) ? ENV_DATA1 : ENV_DATA2);
            variable_s.mName = ENV_NAME1;
            variable_s.mData = ( i % 2) ? ENV_DATA1 : ENV_DATA2;
            variable_s.mHeader.mBase.mObjectSize = sizeof( VBLEnvironmentVariable) + variable_s.mNameLength + variable_s.mDataLength;
            variable_i.mNameLength = strlen( ENV_NAME2);
            variable_i.mDataLength = sizeof( int);
            variable_i.mName = ENV_NAME2;
            variable_i.mData = ( LPBYTE)&i;
            variable_i.mHeader.mBase.mObjectSize = sizeof( VBLEnvironmentVariable) + variable_i.mNameLength + variable_i.mDataLength;
            // write environment variables 
            bSuccess = BLWriteObject( hFile, &variable_s.mHeader.mBase);
            *pWritten += bSuccess ? 1 : 0;
            bSuccess = bSuccess && BLWriteObject( hFile, &variable_i.mHeader.mBase);
            *pWritten += bSuccess ? 1 : 0;
            // write ethernet frame 
            memcpy( ethframe.mSourceAddress, src, sizeof( ethframe.mSourceAddress));
            ethframe.mReserved1 = 0;
            memcpy( ethframe.mDestinationAddress, dst, sizeof( ethframe.mDestinationAddress));
            ethframe.mReserved2 = 0;
            ethframe.mType = 0x0800;
            ethframe.mTPID = 0;
            ethframe.mTCI = 0;
            ethframe.mPayLoadLength = ( WORD)i;
            ethframe.mPayLoad = ethbuffer;
            ethframe.mHeader.mBase.mObjectSize = sizeof( VBLEthernetFrame) + ethframe.mPayLoadLength;
            bSuccess = bSuccess && BLWriteObject( hFile, &ethframe.mHeader.mBase);
            *pWritten += bSuccess ? 1 : 0;
            // write text 
            if ( ( i % 100) == 0)
            {
                char text[128];
                sprintf( text, "%d objects written...", *pWritten);
                appText.mText = text;
                appText.mTextLength = strlen( appText.mText);
                appText.mHeader.mBase.mObjectSize = sizeof( VBLAppText) + appText.mTextLength;
                bSuccess = bSuccess && BLWriteObject( hFile, &appText.mHeader.mBase);
                *pWritten += bSuccess ? 1 : 0;
            }
        }
    }
    appText.mText = "All objects written...";
    appText.mTextLength = strlen( appText.mText);
    appText.mHeader.mBase.mObjectSize = sizeof( VBLAppText) + appText.mTextLength;
    bSuccess = bSuccess && BLWriteObject( hFile, &appText.mHeader.mBase);
    *pWritten += bSuccess ? 1 : 0;
}
/* close file */
if ( !BLCloseHandle( hFile))
{
    return -1;
}
return bSuccess ? 0 : -1;
}`
c#代码:

//translation of C++ struct into C# class
public class VBLEnvVar 
{
public VBLEnvVarStruct variable_s;
public VBLEnvVar()
{
    variable_s = new BLF_Function.VBLEnvVar.VBLEnvVarStruct();
}
public  struct VBLEnvVarStruct
{
    public VBLObjectHeader.VBLObjectHeaderStruct mHeader;
    public uint NameLength;
    public uint DataLength;
    public string Name;
    [MarshalAsAttribute(UnmanagedType.LPArray)]
    public byte[] Data;
}
}
public class VBLAppTrigger 
{
public VBLAppTriggerStruct apptrigger;
public VBLAppTrigger()
{
    apptrigger = new BLF_Function.VBLAppTrigger.VBLAppTriggerStruct(null);
}
public struct VBLAppTriggerStruct
{
    public VBLObjectHeader.VBLObjectHeaderStruct mHeader;
    public UInt64 mPreTriggerTime;
    public UInt64 mPostTriggerTime;
    public ushort mFlags;
    public ushort mChannel;
    public uint mAppSpecific2;
}
}
[DllImport("binlog.dll")]
public static extern bool BLWriteObject( int Handle,ref  BLF_Function.ObjectHeader.ObjHeader pBase);

//how function is called into C# code
public static void Main(string[] args)
{
int written=0;
BLF_Function b = new BLF_Function();
UInt64 time=0;
byte[] ethbuffer = new byte[1500];
bool success=false;
string filename = "provamia.blf";
int Handle = MyBLF.BLCreateFile(filename,b.GENERIC_WRITE);
if (Handle != -1)
{
    success = MyBLF.BLSetApplication( Handle, (byte)BLF_Function.FileStatistics.APPID.BL_APPID_UNKNOWN, 1, 0, 1);
    //***********
    MyBLF.SYSTEMTIME d = new MyBLF.SYSTEMTIME();
    MyBLF.GetLocalTime(out d);
    MyBLF.SYSTEMTIME* s = &d;
    success = MyBLF.BLSetMeasurementStartTime( Handle,ref s);
    //*************
    if (success)
    {
        success = MyBLF.BLSetWriteOptions( Handle, 6,0);
        if (success)
        {
            BLF_Function.VBLObjectHeader vblobjectheaderclass = new BLF_Function.VBLObjectHeader();
            BLF_Function.ObjectHeader objectheaderclass = new BLF_Function.ObjectHeader();
            vblobjectheaderclass.mHeader.baseheader=objectheaderclass.baseheader;
            BLF_Function.VBLAppTrigger apptriggerclass = new BLF_Function.VBLAppTrigger();
            apptriggerclass.apptrigger.mFlags=(ushort)vblobjectheaderclass.BL_OBJ_FLAG_TIME_ONE_NANS;
            apptriggerclass.apptrigger.mHeader=vblobjectheaderclass.mHeader;
            apptriggerclass.apptrigger.mHeader.baseheader.HeaderSize = apptriggerclass.apptrigger.mHeader.GetSize();
            apptriggerclass.apptrigger.mHeader.baseheader.HeaderVersion = 1;
            apptriggerclass.apptrigger.mHeader.baseheader.signature = objectheaderclass.BL_OBJ_SIGNATURE;
            apptriggerclass.apptrigger.mHeader.baseheader.ObjectSize = (ushort)apptriggerclass.GetSize();
            apptriggerclass.apptrigger.mHeader.baseheader.ObjectType = (ushort)BLF_Function.ObjectHeader.OBJ_TYPR.BL_OBJ_TYPE_APP_TRIGGER;
            apptriggerclass.apptrigger.mHeader.mObjectFlags = (uint)vblobjectheaderclass.BL_OBJ_FLAG_TIME_ONE_NANS;
            BLF_Function.VBLCANMessage messageclass = new BLF_Function.VBLCANMessage();
            messageclass.message.mHeader=vblobjectheaderclass.mHeader;
            messageclass.message.mHeader.baseheader.HeaderSize = messageclass.message.mHeader.GetSize();
            messageclass.message.mHeader.baseheader.HeaderVersion = 1;
            messageclass.message.mHeader.baseheader.signature = objectheaderclass.BL_OBJ_SIGNATURE;
            messageclass.message.mHeader.baseheader.ObjectSize = (ushort)messageclass.GetSize();
            messageclass.message.mHeader.baseheader.ObjectType = (ushort)BLF_Function.ObjectHeader.OBJ_TYPR.BL_OBJ_TYPE_CAN_MESSAGE;
            messageclass.message.mHeader.mObjectFlags = (uint)vblobjectheaderclass.BL_OBJ_FLAG_TIME_ONE_NANS;
            BLF_Function.VBLEnvVar variable_sclass = new BLF_Function.VBLEnvVar();
            variable_sclass.variable_s.mHeader=vblobjectheaderclass.mHeader;
            variable_sclass.variable_s.mHeader.baseheader.HeaderSize = variable_sclass.variable_s.mHeader.GetSize();
            variable_sclass.variable_s.mHeader.baseheader.HeaderVersion = 1;
            variable_sclass.variable_s.mHeader.baseheader.signature = objectheaderclass.BL_OBJ_SIGNATURE;
            variable_sclass.variable_s.mHeader.baseheader.ObjectType = (ushort)BLF_Function.ObjectHeader.OBJ_TYPR.BL_OBJ_TYPE_ENV_STRING;
            variable_sclass.variable_s.mHeader.mObjectFlags = (uint)vblobjectheaderclass.BL_OBJ_FLAG_TIME_ONE_NANS;
            BLF_Function.VBLEnvVar variable_iclass = new BLF_Function.VBLEnvVar();
            variable_iclass.variable_s.mHeader=vblobjectheaderclass.mHeader;
            variable_iclass.variable_s.mHeader.baseheader.HeaderSize = variable_iclass.variable_s.mHeader.GetSize();
            variable_iclass.variable_s.mHeader.baseheader.HeaderVersion = 1;
            variable_iclass.variable_s.mHeader.baseheader.signature = objectheaderclass.BL_OBJ_SIGNATURE;
            variable_iclass.variable_s.mHeader.baseheader.ObjectType = (ushort)BLF_Function.ObjectHeader.OBJ_TYPR.BL_OBJ_TYPE_ENV_INTEGER;
            variable_iclass.variable_s.mHeader.mObjectFlags = (uint)vblobjectheaderclass.BL_OBJ_FLAG_TIME_ONE_NANS;
            BLF_Function.VBLEthernetFrame ethframeclass = new BLF_Function.VBLEthernetFrame();
            ethframeclass.ethframe.mHeader=vblobjectheaderclass.mHeader;
            ethframeclass.ethframe.mHeader.baseheader.HeaderSize = ethframeclass.ethframe.mHeader.GetSize();
            ethframeclass.ethframe.mHeader.baseheader.HeaderVersion = 1;
            ethframeclass.ethframe.mHeader.baseheader.signature = objectheaderclass.BL_OBJ_SIGNATURE;
            ethframeclass.ethframe.mHeader.baseheader.ObjectType = (ushort)BLF_Function.ObjectHeader.OBJ_TYPR.BL_OBJ_TYPE_ETHERNET_FRAME;
            ethframeclass.ethframe.mHeader.mObjectFlags = (uint)vblobjectheaderclass.BL_OBJ_FLAG_TIME_ONE_NANS;
            BLF_Function.VBLAppText appTextclass = new BLF_Function.VBLAppText();
            appTextclass.appText.mHeader=vblobjectheaderclass.mHeader;
            appTextclass.appText.mHeader.baseheader.HeaderSize = appTextclass.appText.mHeader.GetSize();
            appTextclass.appText.mHeader.baseheader.HeaderVersion = 1;
            appTextclass.appText.mHeader.baseheader.signature = objectheaderclass.BL_OBJ_SIGNATURE;
            appTextclass.appText.mHeader.baseheader.ObjectSize = (ushort)appTextclass.GetSize();
            appTextclass.appText.mHeader.baseheader.ObjectType = (ushort)BLF_Function.ObjectHeader.OBJ_TYPR.BL_OBJ_TYPE_APP_TEXT;
            appTextclass.appText.mHeader.mObjectFlags = (uint)vblobjectheaderclass.BL_OBJ_FLAG_TIME_ONE_NANS;
            for (int h=0;h<ethbuffer.Length;h++)
                ethbuffer[h]=Convert.ToByte(h & 0xFF);
            for (int i = 0; i < 1000 ; ++i)
            {
                    /* increment in milliseconds */
                    time = (uint)(i * 100000);
                    /* setup app trigger object header */
                    apptriggerclass.apptrigger.mHeader.mObjectTimestamp = time;
                /* write app trigger object */
                success = Scrivi(Handle, apptriggerclass.apptrigger.mHeader.baseheader);////NO ERROR
                written += success ? 1 : 0;
                if (success)
                    {
                    string envdata1="01234567";
                    string envdata2="76543210";
                    /* setup CAN object header */
                     messageclass.message.mHeader.mObjectTimestamp = time;
                        /* setup CAN message */
                        messageclass.message.mChannel=1;
                    messageclass.message.mFlags=(byte)vblobjectheaderclass.BL_OBJ_FLAG_TIME_ONE_NANS;
                        messageclass.message.mDLC = 8;
                        messageclass.message.mID = 0x100;
                        char[] supp  = envdata1.ToCharArray();
                    char[] supp2 = envdata2.ToCharArray();
                    messageclass.message.Data = new byte[messageclass.message.mDLC];
                    if ((i%2)==0)
                    {
                        for (int g=0;g<supp.Length;g++)
                        messageclass.message.Data[g] = (byte)supp[g];
                    }
                    else
                    {
                        for (int g=0;g<supp2.Length;g++)
                        messageclass.message.Data[g] = (byte)supp2[g];
                    }
                        /* write CAN message */
                        success = Scrivi(Handle, messageclass.message.mHeader.baseheader);////NO ERROR
                        written += success ? 1 : 0;
                    if (success)
                    {
                    if ((i%3)==0)
                    {
                    /* setup environment variable object headers */
                    variable_sclass.variable_s.mHeader.mObjectTimestamp= time;

                    /* setup environment variables */
                    string envname1="EnvString";
                    string envname2="EnvInt";
                    char[] suppstring1  = envname1.ToCharArray();
                    char[] suppstring2 = envname2.ToCharArray();
                    variable_sclass.variable_s.NameLength = (uint)envname1.Length;
                    variable_sclass.variable_s.DataLength = (uint)(((i%2)==0)?envdata1.Length:envdata2.Length);
                    variable_sclass.variable_s.Name = envname1;
                    variable_sclass.variable_s.Data = new byte[variable_sclass.variable_s.DataLength];
                        if ((i%2)==0)
                        {
                        for (int g=0;g<supp.Length;g++)
                            variable_sclass.variable_s.Data[g] = Convert.ToByte(supp[g]);
                        }
                        else
                        {
                        for (int g=0;g<supp2.Length;g++)
                            variable_sclass.variable_s.Data[g] = Convert.ToByte(supp2[g]);
                        }
                        variable_sclass.variable_s.mHeader.baseheader.ObjectSize = 65;
                        success = Scrivi(Handle, variable_sclass.variable_s.mHeader.baseheader);////ERROR
...........                     
}
public static bool Scrivi(int a, BLF_Function.ObjectHeader.ObjHeader b)
{
return MyBLF.BLWriteObject( a, ref b);
}

CB

系统.AccessViolationException:试图读写受保护的内存

首先,类型HANDLE应该转换为IntPtr,而不是int。

由于结构填充,结构的大小也可能与原始结构不同。在你的c#代码中使用[Structlayout()]属性来控制这个

将c#中的"ref"更改为"out",可以看到c++代码中没有内存分配问题。

相关文章: