【发布时间】:2016-11-12 09:29:22
【问题描述】:
所以,我遇到了“我更改了我的代码但它不起作用,但后来我将它改回来但它仍然不起作用”的老问题。作为作业的一部分,我们一直在使用 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???
}
【问题讨论】:
-
您需要学习一些关键技能才能取得成功。首先当然是源代码控制,非常能够将您的程序恢复到其最初的工作状态。而且您需要学习如何调试本机代码,以便查看生成异常的语句。本网站现有的 Q+A 很好地涵盖了所有内容。并且也许思考一下分配一个 1 字节的保存缓冲区并多次注册一个窗口类的智慧。
-
除了 Hans 的思考之外,我想知道你期望在最后使用 while 循环会发生什么。
-
@rene while 循环用于获取和处理 WndProc 中的消息。在这种情况下,我使用它来获取与播放和录制功能有关的消息。