2016-11-12 72 views
-2

因此,我遇到了「我改變了我的代碼,但它沒有工作,但後來我改回它,但仍然無法工作」的時代老問題。我們一直在使用DLL作爲任務的一部分,教師給我們提供了播放和錄製聲音的代碼,這些代碼應該放入DLL中,然後用在我們自己的C#程序中。昨天,它運行良好,但後來我試圖弄清楚我的一些代碼是否多餘,我設法打破它。C#程序中的Win32 DLL AccessViolationException

從我的主程序調用啓動功能initDialog我現在得到一個AccessViolationException。我很清楚,當你遇到這個問題時,大部分時間都是因爲你正在嘗試使用未初始化的東西。但是,我沒有看到任何會在我的代碼中導致這個問題的東西,調試器也沒有給出任何提示,原因是什麼。

我會發布我的initDialog函數的代碼和下面的變量聲明,如有必要,我可以在以後發佈更多的代碼。我的想法是創建一個無形的窗口來處理我發送的消息,這樣我就不必在C#中處理消息。

static WAVEFORMATEX waveform; 
    static PBYTE* pSaveBuffer; 
    static BOOL  bRecording = FALSE, bPlaying = FALSE, bReverse = FALSE, 
        bPaused = FALSE, bEnding = FALSE, bTerminating = FALSE; 
    static DWORD  dwDataLength, dwRepetitions = 1; 
    static HWAVEIN hWaveIn; 
    static HWAVEOUT hWaveOut; 
    static PBYTE  pBuffer1, pBuffer2, pNewBuffer; 
    static PWAVEHDR pWaveHdr1, pWaveHdr2; 
    static HWND  myHwnd; 
    static TCHAR  szAppName[] = TEXT("Record/Play"), 
    static HINSTANCE hInst; 

    __declspec(dllexport) void CALLBACK initDialog() { 
     WNDCLASS wndclass; 
     MSG msg; 

     wndclass.style = CS_HREDRAW | CS_VREDRAW; 
     wndclass.lpfnWndProc = WinProc; 
     wndclass.cbClsExtra = 0; 
     wndclass.cbWndExtra = 0; 
     wndclass.hInstance = hInst; 
     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 
     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
     wndclass.lpszMenuName = NULL; 
     wndclass.lpszClassName = szAppName; 

     if (!RegisterClass(&wndclass)) { 
      MessageBox(NULL, TEXT("This program requires Windows 95/98/NT"), 
      szAppName, MB_ICONERROR); 
      return; 
     } 

     myHwnd = CreateWindow(szAppName, TEXT("Record/Play"), WS_OVERLAPPEDWINDOW, 
      CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
      NULL, NULL, hInst, NULL); 

     // Allocate memory for wave header 

     pWaveHdr1 = (PWAVEHDR)malloc(sizeof(WAVEHDR)); 
     pWaveHdr2 = (PWAVEHDR)malloc(sizeof(WAVEHDR)); 

     // Allocate memory for save buffer 

     *pSaveBuffer = (PBYTE)malloc(1); 

     while(GetMessage(&msg, NULL, 0, 0)) { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 

在主程序中我有這樣的代碼:

[DllImport("RecordDll.dll", CharSet = CharSet.Auto)] 
    public static extern int initDialog(); 

    public PlayForm() 
    { 
     InitializeComponent(); 
     this.Show(); 
     initDialog();//AccessViolationException??? 
    } 
+1

幾個關鍵技能,你需要學習前進。首先肯定是源代碼管理,*能夠將程序恢復到原來的工作狀態非常重要。而且您需要學習如何調試本機代碼,以便查看哪些語句生成了異常。所有這些都覆蓋了現有的Q + A。也許可以思考一下分配1字節保存緩衝區和多次註冊窗口類的智慧。 –

+0

除了漢斯的思考之外,我想知道你最終會在循環中預期會發生什麼。 – rene

+0

@rene while循環是爲了獲取和處理WndProc中的消息。在這種情況下,我使用它來獲取有關播放和錄製功能的消息。 – user2316502

回答

-1

我想通了。由線產生的異常:

*pSaveBuffer = (PBYTE)malloc(1); 

當我改變了緩衝區是一個雙指針到一個單一的指針我做了不正確的假設,所有我需要做的就是取消對它的引用,然後malloc的單一指針。但是,我從來沒有綁定單指針,所以我無法解引用雙指針。添加這條線解決了這個問題:

pSaveBuffer = (PBYTE*)malloc(1); //this line 
*pSaveBuffer = (PBYTE)malloc(1); 
相關問題