2011-04-14 8 views
1

C++ 비 관리 라이브러리에서 시작하는 C# 래퍼 생성에 문제가 있습니다. 매번 내가 System.AccessViolationException에 빠진다 : 보호 된 메모리를 읽거나 쓰려고 시도했다. 아마도 구조와 요소를 C++에서 C#으로 변환하는 방식에 따라 다르지만 해결 방법을 알지 못합니다. 누군가 나를 도울 수 있습니까?System.AccessViolationException : 보호 된 메모리를 읽거나 쓰려고 시도했습니다.

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("") : _T(""), 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=""; 
        string envdata2=""; 
        /* 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

+0

C# 코드의 어느 행에서 'AccessViolationException'이 발생했는지 표시하면 더 도움이 될 것입니다. –

답변

1

첫째, 유형 HANDLE 값 int하지, IntPtr로 번역합니다.

또한 구조체 패딩으로 인해 구조체의 크기가 원본과 다를 수 있습니다. 이를 제어하려면 C# 코드에서 [Structlayout()] -Attribute를 사용하십시오.

0

C#에서 "ref"를 "out"으로 변경하고 C++ 코드에 메모리 할당 문제가 없음을 확인하십시오.

+0

죄송합니다. 제안 된 모든 변경 사항을 적용했지만 예외가 여전히 같은 지점에서 발생합니다 (예외가 발생하는 정확한 줄은 //// ERROR를 참조하십시오) – CB0

관련 문제