C#中的Win32 DLL程序AccessViolationException

时间:2016-11-12 09:29:23

标签: c# winapi dll

所以,我遇到了一个古老的问题:“我改变了我的代码并且它没有用,但后来我改回来了它仍然无效”。我们一直在使用DLL作为赋值的一部分,教师向我们提供了播放和录制声音的代码,这些代码应该被放入DLL中,然后在我们自己的C#程序中使用。昨天,它工作正常,但后来我试图找出我的一些代码是否多余,我设法打破它。

从主程序调用启动函数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 个答案:

答案 0 :(得分:-1)

我明白了。该行例外生成了例外:

*pSaveBuffer = (PBYTE)malloc(1);

当我将缓冲区更改为单个指针的双指针时,我做出了错误的假设,我所要做的就是取消引用它然后malloc单指针。但是,我从来没有对单指针进行malloced,因此我无法取消引用双指针。添加此行解决了问题:

pSaveBuffer = (PBYTE*)malloc(1); //this line
*pSaveBuffer = (PBYTE)malloc(1);