请问怎么样用VC编写DLL程序!!!!!!!步骤怎么样

解决方案 »

  1.   

    向导生成,添加导出函数,添加def文件即可!
      

  2.   

    建一个DLL的工程就得了呀,把需要写的东西写进去就OK了
      

  3.   

    http://www.vczx.com/article/show.php?id=825
    http://www.vchome.net/tech/dll/dll10.htm
      

  4.   

    在我们实际用软件时,经常可看到许多动态连接库。动态连接库有其自身的优点
    如节省内存、支持多语种等功能,而且,当DLL中的函数改变后,只要不是参数的改变
    调用起的函数并不需要重新编译。这在编程时十分有用。至于其他妙处,各位在电脑
    杂志、书籍中都能看到,我这里再说就是废话了.
    这次小弟我所要讲的是如何在VC5.0中如何做自己的Win32 DLLs,各位要做自己的
    动态连接库,首先要知道DLL在VC5.0中都有哪几种分类。VC支持三种DLL,它们是:1.Non-MFC Dlls
    2.Regular Dlls
    3.Extension Dlls Note:翻译措辞不当,故遇到术语是引用原词Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLL,其输出的函数一
    般用的是标准C接口,并能被非MFC或MFC编写的应用程序所调用。LL,
    Regular DLL:和下述的Extension Dlls一样,是用MFC类库编写的。明显的特点是
    在源文件里有一个继承CWinApp的类。其又可细分成静态连接到MFC和动态连接到MFC上
    的。但静态连接到MFC的动态连接库只被VC的专业般和企业版所支持。
    Extension DLL:用来实现从MFC所继承下来的类的重新利用,也就是说,用这种类
    型的动态连接库,可以用来输出一个从MFC所继承下来的类。Extension DLL使用MFC的
    动态连接版本所创建的,并且它只被用MFC类库所编写的应用程序所调用。
    各位看到这里如果眼有点花或头有点晕,请别泄气,再看两遍,然后继续往下看,
    定有收获。标 题: 关于VC中的DLL的编程[1]这一节介绍Non-MFC DLLs的编写方法。下面是一个通用的
    写法:BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,
    LPVOID lpReserved)
    {
    switch( ul_reason_for_call ) {
    case DLL_PROCESS_ATTACH:
    .......
    case DLL_THREAD_ATTACH:
    .......
    case DLL_THREAD_DETACH:
    .......
    case DLL_PROCESS_DETACH:
    .......
    }
    return TRUE;
    }
    每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,
    必须有一个WINMAIN函数一样。
    在这个示例中,DllMain是一个缺省的入口函数,你不需要编写自己
    的DLL入口函数,并用linker的命令行的参数开关/ENTRY声明。用这个缺
    省的入口函数就能使动态连接库被调用时得到正确的初始化,当然了,你
    不要在初始化的时候填写使系统崩溃的代码了。
    参数中,hMoudle是动态库被调用时所传递来的一个指向自己的句柄
    (实际上,它是指向_DGROUP段的一个选择符)
    ul_reason_for_call是一个说明动态库被调原因的标志。当进程或线程
    装入或卸载动态连接库的时候,操作系统调用入口函数,并说明动态连接库
    被调用的原因。它所有的可能值为:
    DLL_PROCESS_ATTACH: 进程被调用
    DLL_THREAD_ATTACH: 线程被调用
    DLL_PROCESS_DETACH: 进程被停止
    DLL_THREAD_DETACH: 线程被停止
    lpReserved是一个被系统所保留的参数。
    入口函数已经写了,盛下的也不难,你可以在文件中加入你所想要输
    出的函数或变量或c++类或、或、或、?好象差部多了。Look here!现在就
    要加入一个新的输出函数了:
    void _declspec(dllexport) JustSoSo()
    {
    MessageBox(NULL,"It's so easy!","Hahaha......",MB_OK);
    }
    要输出一个类也可以,如下:
    class _declspec(dllexport) Easy
    {
    //add your class definition...
    };
    各位一定注意到在输出函数或类是我用到_declspec(dllexport),
    这是VC提供的一个关键字,用它可在动态连接库中输出一个数据、
    一个函数或一个类。用这个关键字可省你不少事,你不用在.DEF文件
    中说明我要输出这个类、那个函数的。
    Ok!各位照着上面的例子试着敲敲看,Just so easy!
    先说到这了
    发信人: dragon (龙), 信区: VC
    标 题: 关于VC中的DLL的编程[2]前面讲到Non-MFC DLL的编法,现在讲讲调用DLL的方法。对DLL的
    调用分为两种,一种是显式的调用,一种是隐式的调用。
    所谓显式的调用,是指在应用程序中用LoadLibrary或MFC提供的
    AfxLoadLibrary显式的将自己所做的动态连接库调近来,动态连接库
    的文件名即是上两函数的参数,再用GetProcAddress()获取想要引入
    的函数。自此,你就可以象使用如同本应用程序自定义的函数一样来
    调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或
    MFC提供的AfxLoadLibrary释放动态连接库。
    隐式的调用则需要把产生动态连接库时产生的.LIB文件加入到应
    用程序的工程中,想使用DLL中的函数时,只须说明以下,如下:说明
    上篇的输出函数void JustSoSo();
    隐式调用不需要调用LoadLibrary()和FreeLibrary().由此看来,隐式说明调用的方法比较简单,但DLL改变后,应用程序
    须从新编译。并且,所有所调用的DLL在应用程序加载的同时被加载到内
    存中,但应用程序调用的DLL比较多时,装入的过程十分慢。隐式的调用
    则在应用程序不知道所要装入的DLL或隐式调用不成功,此时,允许用户
    指定所要加载的动态连接库,比较灵活发信人: dragon (龙), 信区: VC
    标 题: 关于VC中的DLL的编程[3]Regular DLL能够被所有支持DLL技术的语言所编写的应用程序
    所调用。在这种动态连接库中,它必须有一个从CWinApp继承下来的
    类,DllMain函数被MFC所提供,不用自己显式的写出来。下面是一个
    例子:
    // MyRegularDll.h:main header file for the MYREGULARDLL DLL
    #include "resource.h" // main symbolsclass CMyRegularDllApp : public CWinApp
    {
    public:
    CMyRegularDllApp();
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMyRegularDllApp)
    //}}AFX_VIRTUAL//{{AFX_MSG(CMyRegularDllApp)
    // NOTE - the ClassWizard will add and
    // remove member functions here.
    // DO NOT EDIT what you see in these blocks
    // of generated code !
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    };//MyRegularDll.cpp:Defines the initialization routines for the DLL.
    //#include "stdafx.h"
    #include "MyRegularDll.h"
    // Note!
    //
    // If this DLL is dynamically linked against the MFC
    // DLLs, any functions exported from this DLL which
    // call into MFC must have the AFX_MANAGE_STATE macro
    // added at the very beginning of the function.
    //
    // For example:
    //
    // extern "C" BOOL PASCAL EXPORT ExportedFunction()
    // {
    // AFX_MANAGE_STATE(AfxGetStaticModuleState());
    // // normal function body here
    // }
    //
    // It is very important that this macro appear in each
    // function, prior to any calls into MFC. This means that
    // it must appear as the first statement within the
    // function, even before any object variable declarations
    // as their constructors may generate calls into the MFC
    // DLL.BEGIN_MESSAGE_MAP(CMyRegularDllApp, CWinApp)
    //{{AFX_MSG_MAP(CMyRegularDllApp)
    // NOTE - the ClassWizard will add
    // and remove mapping macros here.
    // DO NOT EDIT what you see in these blocks
    END_MESSAGE_MAP()
    ////////////////////////////////////////////////////////////
    // CMyRegularDllApp construction
    CMyRegularDllApp::CMyRegularDllApp()
    {
    // TODO: add construction code here,
    // Place all significant initialization in InitInstance
    }
    以上是AppWizard产生的含有主要代码的两个文件,各位可从中
    看出和Non-MFC Dlls的区别。但要注意上面的AppWizard的提醒啊。发信人: dragon (龙), 信区: VC
    标 题: 关于VC中的DLL的编程[4]
    发信站: 饮水思源站 (Thu Mar 25 00:46:22 1999) , 站内信件这次要讲的是最后一种动态连接库:Extension Dlls.再次说明,
    Extension Dll只被用MFC类库所编写的应用程序所调用.在这种动态
    连接库中,你可以从MFC继承你所想要的、更适于你自己用的类,并
    把它提供给你的应用程序。你也可随意的给你的应用程序提供MFC或
    MFC继承类的对象指针。
    Extension DLLs 和Regular DLLs不一样,它没有一个从CWinApp
    继承而来的类的对象,所以,你必须为自己DllMain函数添加初始化
    代码和结束代码.如下:#include "stdafx.h"
    #include static AFX_EXTENSION_MODULE PROJNAMEDLL = { NULL, NULL };extern "C" int APIENTRY
    DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
    {
    if (dwReason == DLL_PROCESS_ATTACH)
    {
    TRACE0("PROJNAME.DLL Initializing!\n");// Extension DLL one-time initialization
    AfxInitExtensionModule(PROJNAMEDLL,
    hInstance);// Insert this DLL into the resource chain
    new CDynLinkLibrary(Dll3DLL);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
    TRACE0("PROJNAME.DLL Terminating!\n");
    }
    return 1; // ok
    }
    在上面代码中AfxInitExtensionMoudle函数捕捉此动态库模块
    用.
    在初始化的时NEW一个CDynLinkLibrary对象的目的在于:它
    能是Extension DLL想应用程序输出CRuntimeClass对象或资源.
    如果此动态连接库被显式的调用,还必须在DLL_PROCESS_DETACH
    选择项的执行代码上调用AfxTermEXtensonModule,这保证了当调
    用进程与动态连接库分离是正确清理内存中的动态库模块。如果是
    隐式的被调用,则此步不是必须的了。
      

  5.   

    下面的例子是一个纯资源DLL的源程序纯资源的DLL就是只包含资源的DLL,例如:图标,位图,字符串,声音,视频,对话框等。使用纯资源DLL可以节约可执行文件的大小,可以被所有的应用程序所共享,从而提高系统性能。纯资源DLL的编写比普通的DLL要简单的多,首先创建一个WIN32 DLL工程,不是MFC的DLL,然后创建一个资源文件 *.RC,添加到资源DLL的工程中去。然后添加一个初始化DLL的原文件。
    #include <windows.h>extern "C"
    BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID )
    {
        return 1;
    }这是纯资源DLL所必须需的代码,保存这个文件为*.CPP。编译这个资源DLL。在应用程序显示的调用这个DLL,使用LoadLibrary函数装入资源DLL,FindResource和LoadResource来装入各种资源,或者使用下列的特定的资源装入函数: FormatMessage 
    LoadAccelerators 
    LoadBitmap 
    LoadCursor 
    LoadIcon 
    LoadMenu 
    LoadString 
    当资源使用结束,你的应用程序须调用FreeLibrary函数来释放资源。下面就讲一下如何调用编写好的资源DLL首先在应用程序中声明一个DLL的句柄,HINSTANCE m_hLibrary;在OnCreate( )函数中调用LoadLirbrary( ),在OnDestory( )中调用FreeLibrary()。下载一个工程文件看一看,就什么都搞定了。
      

  6.   

    建议楼主阅读一本相关书籍。比如<Windows核心编程>
      

  7.   

    1、第一步创建一“MFC AppWizard (dll)”工程,接下来选择“Regular Dll using shared MFC DLL”,点击“Finish”。2、添加一对话框资源到工程中,从菜单中选择Insert->Resource,添加一“Dialog”
    选择“New”,至此对话框已添加到DLL工程中。3、为对话框添加一新类,如:CTest,基类为CDialog。4、在MFCDLL.cpp中(因创建的工程为MFCDLL)添加接口函数:extern "C" __declspec(dllexport) void Show(){        AFX_MANAGE_STATE(AfxGetStaticModuleState());        CTest test;        test.DoModal ();}别忘了在文件中添加: #include "Test.h":),大功告成,编译吧! 5、用VC新建一对话框工程,在一按钮点击事件中添加如下代码: typedef void (WINAPI * TESTDLL)();  HINSTANCE hmod;hmod = ::LoadLibrary ("mfcdll.dll");if(hmod==NULL){        AfxMessageBox("Fail");}TESTDLL lpproc;lpproc = (TESTDLL)GetProcAddress (hmod,"Show");if(lpproc!=(TESTDLL)NULL)        (*lpproc)();FreeLibrary(hmod);6、试试看,是不是DLL中对话框显示出来了:)
      

  8.   

    下面通过例子介绍如何在动态链接库中定义函数、资源、和类以及如何在工程中使用动态链接库中已定义的函数、资源、类。一、 函数的定义和使用方法:  第一步:   运行AppWizard,定义项目名为mydll,选择MFC AppWizard(dll),而不是MFC AppWizards(exe)。  第二步:   在这个例子中,只有一个AppWizard屏幕出现,选择MFC扩展DLL(MFC Extension DLL (using shared MFC DLL),点击FINISH生成工程。  第三步:   点击File中的New,选择C/C++ Header File,File Name中输入dll,点击OK,创建dll.h。输入extern "C" __declspec(dllexport) int fun(int x1,int x2,int x3); ,保存。  第四步:   点击File中的New,选择C++ Source File,File Name中输入dll,点击OK,创建dll.cpp。输入  #include "stdafx.h"
      #include "dll.h"
      extern "C" __declspec(dllexport) int fun(int x1,int x2,int x3)
       {
        return x1+x2+x3;
       }  编译生成mydll.dll和mydll.lib。  第五步:  选择Project 中Add To Project 中的New , 重新生成一个工程,选择MFC AppWizards(exe),项目名为mydlltest , 选择Single Document ,点击FINISH,生成一个新的工程。选择菜单中的Project àSet Active Project àmydlltest ,将mydlltest设为当前活动工程。  第六步:  拷贝…\mydll\debug\mydll.dll 到 ..\mydlltest\debug\下,拷贝…\mydll\debug\mydll.lib到…\mydlltest\目录下。  第七步:  在mydlltestView.cpp中的#endif下添加  extern "C" __declspec(dllimport) int fun(int x1,int x2,int x3);  在void CMydlltestView::OnDraw(CDC* pDC)中添加代码如下:  void CMydlltestView::OnDraw(CDC* pDC)
       {
        CMydlltestDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
        // TODO: add draw code for native data here
        int x=fun(1,2,3);
        CString str;
        str.Format("%d",str);
        pDC->TextOut(10,10,x);
       }  第八步:  在WorkSpace中的mydlltest files上点击右键,选择Add files to Project ,将mydll.dll添加到工程。
    好了,我们的工作做完了,运行一下看看吧!二、 类的添加和使用步骤:  在mydll中生成一个新类,类的声明处改为class AFX_EXT_CLASS CMyClass ,在此类中和其他类一样添加自己需要的变量和函数,编译生成新的dll和lib,重复上面的第六步,在mydlltest中利用上面的方法生成一个myclass.h文件,拷贝mydll中myclass.h的所有代码到新生成的myclass.h中。在需要使用dll中CmyClass类的文件中包含myclass.h,然后我们就可以向其他类一样使用该类了。  三、 字符串的定义和使用  在mydll中定义字符串资源,编译生成新的dll和lib,重复上面的第六步,在mydlltest中的myclass.h中添加 #define IDS_MYSTR 1(假设我们定义的字符串资源的ID号为IDS_MYSTR),在需要是要该字符串的地方添加#include "myclass.h",即可使用该字符串了。  CString str2;
      str2.LoadString(IDS_MYSTR);  四、 对话框的定义和使用  在mydll中定义对话框资源,生成一个新类CDlg,类的声明处改为class AFX_EXT_CLASS CDlg : public CDialog ,像其他对话框一样定义对话框的属性和功能,编译生成新的dll和lib,重复上面的第六步,在mydlltest中利用上面的方法生成一个dlg.h文件,拷贝mydll中dlg.h的所有代码到新生成的dlg.h中。在需要使用dll中此对话框资源的文件中包含dlg.h,然后我们就可以向其他对话框一样使用此对话框了。  CDlg dlg;
      dlg.DoModal();   好了,到这里我们所有的功能就都实现了,快编译运行一下吧!