不知道大家在调用 HINSTANCE hInstance=NULL; hInstance=::LoadLibrary("Dll Path"); 的时候有没有发现在载入DLL的时候,它的返回传值hInstance始终是为0的,也就是说,如果我们想在我的程序中给DLL文件中的窗口或者函数传递参数是没有办法的。因为我们没有办法来调用DLL的入口函数。所以说呢,我们这样生成的DLL文件其实意义并不是很大的,只相当于我们以另一种形式在我们的当前的程序用调用了另一个小程序或者说的窗口。 既然有问题,那我们就要解决,但还是有必要来分析一下为什么我们的LoadLibrary的返回总是为0呢,难道是说我们没有载入或者说是载入失败,不可能的如果是这样那我们的程序为什么会运行起来的,那看来还是别有蹊跷的。 大家不会忘记在InitInstance()中有下面这样一段代码吧: CResourceDDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } 看到这里的时候,想必大家已经知道引起问题的罪魁祸首是谁了吧!不错就是那个DoModal()正是由于它的存在,才使我们的程序在被成功加载的之后,没有返回我们所想要的值。因为在我们的程序在调用DLL的时候,(在MFC中程序的执行顺序我在这里就不再多说了,大家应该非常清楚的)当执行到了DoModall的时候(说到这里我感觉我还是有必要和大家讨论一下VC中的对话框:在VC中对话框分为两类一是模式对话框二是无模式对话框。两者的主要区别在于:<1>显示模式对话框需要调用CDialog::DoMaodal,而显示模式对话框则要调用CDialog::Create.DoModal要等到对话框被消除之后才返回。而和DoModal不同,一旦建立对话框,Create就返回,因此,Create返回时对话框还处于显示状态。<2>清除模式对话框要调用DestroyWindow,而不是EndDialog.禁止对无模式对话框调用CDialog::OnOk或CDialog::OnCancel,因为两者都调用EndDialog.<3>模式对话框类通常在堆栈上实例化,所以析构是自动实现的,而无模式对话框通过NEW实例化,所以该对话框对象不会过早地被消除。如果要确保消除对话框时删除无模式对话框对象,一种方法是在派生的对话框类中覆盖CDialog::PostNcDestroy并执行delete this语句.当然模式对话框我无模式对话框还是有区 别的,不过今天我们就只提到对我们有用的。有兴趣的大家可以自己研究),也就是说欠产在调用一个模式对话框并且让它显示了出来,但是我们不要忘记上面提到的模式对话框的特点,DoModal一定要等到对话框被返回的时候,才被消息,所以呢当我们在执行的时候,我们的DLL文件一但进入到这里面的时候,除非清除它否则我们是无法返回的。这也就造成了为什么我们的返回值一直为空, 知道产生这个问题的原因了,接下来要解决这个问题也很简单。 造成没有返回值的原因是因为模式对话框,那好了,我们不用它了,改成无模式对话框那总好了吧。所以我们的代码修改如下: BOOL CDemoDllApp::InitInstance() { AfxEnableControlContainer();
// Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. /* #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif*/ /****************利用无模式对话框*************************/ pDlg=new CDemoDllDlg; m_pMainWnd = pDlg; pDlg->Create(IDD_DEMODLL_DIALOG); pDlg->ShowWindow(SW_HIDE); // int nResponse = pDlg->DoModal(); /* if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) // { // TODO: Place code here to handle when the dialog is // dismissed with Cancel // } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. */ return true;//一定要返回TRUE