原本有一个对话框形式的exe文件,其中主对话框有各种菜单响应函数,及其数不清的控件为了模块化需要,需要将其制作成一个DLL给主工程的对话框调用,加载到主工程对话框的界面上,与主对话框进行交互响应。。现在问题是,我新建了一个支持MFC的DLL工程,然后把那个exe之中的资源与文件都加载进去之后,应该如何定义这个DLL工程的对外接口,一边主工程的对话框可以很方便地调用呢????

解决方案 »

  1.   

    但是在建立DLL工程的时候,我选定支持MFC所以系统已经自动帮我生产了一些代码。。在对外接口的cpp文件里有个:int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
    int nRetCode = 0; // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
    // TODO: change error code to suit your needs
    _tprintf(_T("Fatal Error: MFC initialization failed\n"));
    nRetCode = 1;
    }
    else
    {
    // TODO: code your application's behavior here. } return nRetCode;
    }我该继续怎么做???
    我将 接口头文件里面的 接口类
    class IBODLL_API CIBODLL {
    public:
    CIBODLL(void);
    // TODO: add your methods here.};
    换成了主对话框的类了,然后只需要在cpp里面实现就可以了吗???
    那上面那个主接口main函数我怎么利用它访问到我的接口类呢??
      

  2.   

    你在DLL中创建一个全局函数CreateInstance(), 在这个全局函数中生成一个你的类的对象并返回他的地址,你在EXE中使用loadlibrary+getprocaddress得到并执行该CreateInstance(),这样你不就得到了这个对象的地址了吗。接下来就可以使用这个对象来做事了。
      

  3.   

    不好意思,不是很明白你说利用CreateInstance()的方法, 请问能帮忙给出具体定义接口的代码吗我尝试静态加载DLL,但把头文件和lib搬过去之后,资源又无法识别了。。哎,晕了
      

  4.   

    我只能给出一些思路供你思考,具体的细节当然要你自己来做啦。
    静态加载肯定也可以,不过遇到一点问题是难免的啊,耐心的查找原因,会解决的。
    你现在已经生成了lib 和DLL?
      

  5.   


    我就把那个类定义成了接口,没用到系统给出的int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 函数接口, 屏蔽了这个函数,直接在接口的cpp中对接口类进行实现这样可以么?
    然后生成DLL和LIB都没问题的,于是加载到工程之中。出现资源冲突的问题,DLL之中的资源工程无法识别
      

  6.   

    http://topic.csdn.net/u/20100115/20/3b8fccad-2b06-4797-abc3-41528b6ca8bd.html
    你参考这篇文章,看看能不能解决你的资源问题。
      

  7.   

    你可以看一下Winamp的插件的接口定义,网上有好多介绍的
      

  8.   

    还是没解决,8楼推荐的那篇文章很好,但还是不明白如何在实际之中应用
    我现在是在DLL的接口函数中这么实现的:
    int ShowIBODlg(bool bShowIBODlg)
    {
    AFX_MANAGE_STATE(AfxGetStaticModuleState()); CIBODlg Dlg;
    Dlg.DoModal();
    return 0;
    }
    上面的CIBODlg是DLL中主对话框资源所对应的类。   然后我再主工程之中动态加载:
    HINSTANCE hInstance; 
    hInstance = ::LoadLibrary("../lib/IBODLL.dll"); 
    if(!hInstance) 

    //MessageBox("LoadLibrary is falied!"); 
    //return; 


    AfxSetResourceHandle(hInstance);//把DLL设置为本地资源 FreeLibrary(hInstance);
    加载后主工程的编译通过,但在运行的时候,断点在
    hInstance = ::LoadLibrary("../lib/IBODLL.dll"); 时出现异常,
    进入异常,程序跳到系统文件appcore.cpp之中CWinApp::CWinApp(LPCTSTR lpszAppName)的:
    ASSERT(AfxGetThread() == NULL);  此处。。请问各位大牛,这主要的原因是什么???谢谢
      

  9.   

    LoadLibrary("../lib/IBODLL.dll")没有成功执行。你试试LoadLibrary("..\lib\IBODLL.dll")
      

  10.   


    不是这个原因。。那写法没错。谢谢你的帮助。。还是我对MFC的基础打得不好,哎
      

  11.   

    你试试去掉编译选项中的/MDd.
    另外,你的dll是选择的regular dll...还是mfc extension dll?
    你的exe是mfc程序?
      

  12.   

    对,DLL是支持MFC扩展的mfc extension dll。exe也是一个mfc程序,我需要完成的就是在exe的主对话框界面之中某一区域显示或者隐藏DLL之中的对话框。。
    现在就是在LoadLibrary("../lib/IBODLL.dll")  这里直接异常到
    ASSERT(AfxGetThread() == NULL);
    网上找了一下,还是没头绪。
      

  13.   


    1 调试看看你的CWinApp::CWinApp(LPCTSTR lpszAppName)执行了几次,如果超过一次就是有问题2 我试了一下,我做的这个DLL可以正常载入,你这样试试,做一个空的DLL,先载入看成不成功,成功后一点点往里面加东西,就大约可以查到出错的地方了吧。
      

  14.   


    CWinApp::CWinApp(LPCTSTR lpszAppName)执行了两次,加载DLL之前成功执行一次
    调试到LoadLibrary("../lib/IBODLL.dll") 之后再次执行,就会报出
    ASSERT(AfxGetThread() == NULL);  异常。。
      

  15.   

    哦,那好,基本可以确定就是这个问题了,如果有两个CWinApp的对象生成的话,第二次就会出现你的这个错误了。
      

  16.   


    为啥会有两个咧。是不是我需要注释掉DLL资源里面的那个?
      

  17.   

    一个空的mfc mfc extension dll是可以加载成功的。我现在试试将资源和各种文件加载进去
      

  18.   

    可能因为你的DLL是MFC extensions dll吧。
    应该要除掉DLL中那个(如果没有什么副作用的话。)一个程序不能有两个CWinApp啊。
      

  19.   

    先不要加了,你调试看看第二个Cwinapp是怎么回事吧。
      

  20.   

    去掉DLL之中的那个Cwinapp是可以编译通过,运行也没有异常的。。但对话框资源弹不出来,调试加载动态库之后第二次运行的Cwinapp,就是上面说的出现那个断点异常ASSERT(AfxGetThread() == NULL);