精华内容
下载资源
问答
  • 如何用vc编写dll文件 ...我们利用VC编写DLL有几种方法.如果用VC建立一个WIN32 DLL 工程.那这个工程就应该只导出C++的类或全局变量.和全局函数.方法就是在CPP文件中编写你的代码,为每个需要导出的...
     

    如何用vc编写dll文件

    动态连接库最大的特点就是能节省磁盘空间.当多个进程共享同一个DLL的时候,内存中只有一个DLL的代码.通过映射来使各个进程得以调用.

    1.用VC建立一个WIN32 DLL

    我们利用VC编写DLL有几种方法.如果用VC建立一个WIN32 DLL 工程.那这个工程就应该只导出C++的类或全局变量.和全局函数.方法就是在CPP文件中编写你的代码,为每个需要导出的元素进行导出办法是增加如下语句:

    _declspec(dllexport)

    你当然可以把它定义成宏

    例如,如果是一个类STUDENT需要导出, 那么声明时应该是这样写 class _declspec{dllexport) student;

    当然也可以定义时直接导出.

    我们的客户端,也就是我们调用该函数的客户程序,就需要导入这个类或者函数..

    填写如下语句:

    class _declspec(dllimport) student

    {

    }  // 声明

    之后就可以利用STUDENT来构造对象,也可以调用它的成员函数..了

    记住,一定要把工程的连接设置好.要把生成的LIB文件填写好,因为客户程序要想加载DLL,能够准确的调用各个DLL中的函数,都是靠这个LIB文件哪.包括函数的地址等等.

    当然也可以显示连接

    利用LOADLIBRARY

    原型是

    HMODULE LoadLibrary( LPCTSTR);

    返回的HMODULE就是一个DLL句柄.

    所以我们在利用这个句柄来作为参数调用另一个函数GETPROCADDRESS

    FARPROC GetProcAddress( HMODULE  , LPCSTR);  //如果利用序号来索引,那么要加上MAKEINTERSOURCE宏

    返回一个函数指针,利用它来调用函数,

    LPCSTR是函数名,但你应该利用DUMPBIN来查看一下你导出的函数名,因为C++编译器支持重载,它会以自己的方式重命名.除非你用extern "C"

    用C语言的方式来命名函数.例如 一个函数 void fun();

    导出格式应该是 extern "C" _declspec(dllexport) void fun();   //如果是声明导入函数,直接写原型,如果是声明类,那么一定要是类的头文件声明,包含了成员函数和数据成员的.

    注意即使是采用了C语言命名方式 如果你改变了调用方式_stdcall 那么还是会改变函数命名的,除非你利用DEF文件来导出.

    EXPORTS

    fun

    这样是可以的.

     

    2.建立一个MFC扩展DLL

    扩展DLL是为了更好的支持MFC的类.你建立这个工程后会自动生成一些代码,不要管它先,你把你要动态连接的CPP和相应的.H文件加入到工程,在.CPP文件中需要导出的类上加上AFX_EXT_Class 在.H需要导入的类上加上同样的代码,这样就可以了.

    例如class AFX_EXT_CLASS CSTUDENT : public CPERSON   //.CPP

    {

    }

    class AFX_EXT_CLASS CSTUDENT ; //.H

    {

    }   //声明

    3.建立一个常规的DLL

    如果你要建立扩展的DLL,那么其他的IDE是无法利用的,因为每个编译器的命名方式是不同的.

    如果你想使其他IDE来调用VC的DLL,那么就建立一个常规的DLL.

    建立工程以后,编写你要导出的类.例如

    extern "C" _declspec(dllexport) void fun()

    {

        AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

    }

    在为每一个需要导出的函数的开头加上这条语句.

    在客户端要加上导入语句就可以了.

    方法二:

    在我们实际用软件时,经常可看到许多动态连接库。动态连接库有其自身的优点
    如节省内存、支持多语种等功能,而且,当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 symbols 
    
    class 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() 
    { 
    // TOD 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,这保证了当调
    用进程与动态连接库分离是正确清理内存中的动态库模块。如果是
    隐式的被调用,则此步不是必须的了。

    转载于:https://www.cnblogs.com/lihaozy/archive/2012/08/08/2628431.html

    展开全文
  • 如何用vc编写dll文件

    2010-09-10 09:55:00
    VC建立一个WIN32 DLL 我们利用VC编写DLL有几种方法.如果用VC建立一个WIN32 DLL 工程.那这个工程就应该只导出C++的类或全局变量.和全局函数.方法就是在CPP文件中编写你的代码,为每个需要导出的元素进行导出...

    如何用vc编写dll文件

    动态连接库最大的特点就是能节省磁盘空间.当多个进程共享同一个DLL的时候,内存中只有一个DLL的代码.通过映射来使各个进程得以调用.

    1.用VC建立一个WIN32 DLL

    我们利用VC编写DLL有几种方法.如果用VC建立一个WIN32 DLL 工程.那这个工程就应该只导出C++的类或全局变量.和全局函数.方法就是在CPP文件中编写你的代码,为每个需要导出的元素进行导出办法是增加如下语句:

    _declspec(dllexport)

    你当然可以把它定义成宏

    例如,如果是一个类STUDENT需要导出, 那么声明时应该是这样写 class _declspec{dllexport) student;

    当然也可以定义时直接导出.

    我们的客户端,也就是我们调用该函数的客户程序,就需要导入这个类或者函数..

    填写如下语句:

    class _declspec(dllimport) student

    {

    }  // 声明

    之后就可以利用STUDENT来构造对象,也可以调用它的成员函数..了

    记住,一定要把工程的连接设置好.要把生成的LIB文件填写好,因为客户程序要想加载DLL,能够准确的调用各个DLL中的函数,都是靠这个LIB文件哪.包括函数的地址等等.

    当然也可以显示连接

    利用LOADLIBRARY

    原型是

    HMODULE LoadLibrary( LPCTSTR );

    返回的HMODULE就是一个DLL句柄.

    所以我们在利用这个句柄来作为参数调用另一个函数GETPROCADDRESS

    FARPROC GetProcAddress( HMODULE  , LPCSTR);  //如果利用序号来索引,那么要加上MAKEINTERSOURCE宏

    返回一个函数指针,利用它来调用函数,

    LPCSTR是函数名,但你应该利用DUMPBIN来查看一下你导出的函数名,因为C++编译器支持重载,它会以自己的方式重命名.除非你用extern "C"

    用C语言的方式来命名函数.例如 一个函数 void fun();

    导出格式应该是 extern "C" _declspec(dllexport) void fun();   //如果是声明导入函数,直接写原型,如果是声明类,那么一定要是类的头文件声明,包含了成员函数和数据成员的.

    注意即使是采用了C语言命名方式 如果你改变了调用方式_stdcall 那么还是会改变函数命名的,除非你利用DEF文件来导出.

    EXPORTS

    fun

    这样是可以的.

    2.建立一个MFC扩展DLL

    扩展DLL是为了更好的支持MFC的类.你建立这个工程后会自动生成一些代码,不要管它先,你把你要动态连接的CPP和相应的.H文件加入到工程,在.CPP文件中需要导出的类上加上AFX_EXT_Class 在.H需要导入的类上加上同样的代码,这样就可以了.

    例如class AFX_EXT_CLASS CSTUDENT : public CPERSON   //.CPP

    {

    }

    class AFX_EXT_CLASS CSTUDENT ; //.H

    {

    }   //声明

    3.建立一个常规的DLL

    如果你要建立扩展的DLL,那么其他的IDE是无法利用的,因为每个编译器的命名方式是不同的.

    如果你想使其他IDE来调用VC的DLL,那么就建立一个常规的DLL.

    建立工程以后,编写你要导出的类.例如

    extern "C" _declspec(dllexport) void fun()

    {

        AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

    }

    在为每一个需要导出的函数的开头加上这条语句.

    在客户端要加上导入语句就可以了.

    方法二:

    在我们实际用软件时,经常可看到许多动态连接库。动态连接库有其自身的优点
    如节省内存、支持多语种等功能,而且,当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 symbols

    class 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()
    {
    // TOD 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,这保证了当调
    用进程与动态连接库分离是正确清理内存中的动态库模块。如果是
    隐式的被调用,则此步不是必须的了。

    展开全文
  • VC工程名称转换程序

    2007-05-03 00:18:40
    VC++工程名称转换程序 <br/>简介: 如果您用VC++创建了一个庞大复杂的工程,而您又想重新命名它,这个软件将助您在短短秒钟内完成,减少了繁重的手动更改劳动! 如果您想在以前用VC++创建的工程...
  • 我们利用VC编写DLL有几种方法.如果用VC建立一个WIN32 DLL 工程.那这个工程就应该只导出C++的类或全局变量.和全局函数.方法就是在CPP文件中编写你的代码,为每个需要导出的元素进行导出办法是增加如下语句:

    一、动态链接库介绍(DLL) 

    1.     Non-MFC DLL: 指的是不用MFC的类库,直接用C语言写的DLL,其输出的函数一般用的是标准C接口,并能被非MFC或MFC编写的应用程序所调用。 

    2.     Regular DLL:和下述的Extension Dlls一样,是用MFC类库编写的。明显的特点是在源文件里有一个继承CWinApp的类。

            又可细分成静态连接到MFC和动态连接到MFC。但静态连接到MFC的动态连接库只被VC的专业般和企业版所支持。 

             静态链接到MFC的动态链接库:这种DLL在链接过程中会将使用到的MFC类库复制一份到最终的DLL文件中,最终生成的DLL比较庞大且加载时不是很方便,但它可以在没有MFC类库DLL文件的机器上使用。 

              动态链接库使用共享MFC DLL:这种DLL不会将用到的MFC类库复制到最终生成的DLL中,因此最终的DLL比较小,加载也很方便,但在没有MFC类库DLL文件的机器上无法使用,必须有MFC类库的支持。 

     3.Extension DLL: 

    MFC扩展DLL,可以实现从MFC所继承下来的类的重新利用,可以导出C++类以及MFC派生类,使用这种DLL必须有MFC类库的支持,也就是说它只被用MFC类库所编写的应用程序所调用。 

     

    二、编写Non-MFC dll 

    1、打开visual studio 2008 

    2、file->new->Project… 

    3 、在弹出的“New project”窗口中,prject types子窗口中选择 visual C++,Templates子窗口中选择Win32 Project,然后在name处输入 pow,location处输入F:/vc2008dll,点击“OK” 

    4、在弹出的“win32 application wizard - pow”窗口中,点击“Next”; 

    5、在弹出的“win32 application wizard - pow”窗口中,Application type选项中选择DLL,Additional options选项中选择Export symbols,点击“Finish” 

    工程会自动生成对应的文件和代码,生成了pow.h和pow.cpp 

    6、在pow.h的文件末尾添加pow函数的声明 

    POW_API int pow(const int& x,const int& y);  

    //POW_API是自动生成的一个宏,它的作用是表明该函数是导入还是导出的 

    7、在Pow.cpp中添加pow函数的实现 

    POW_API int pow(const int& x,const int& y) 

    {    int z=1;

        for(int i=0;i<y;i++) 

            z*=x;

        return z; 

    }

    编译后会在debug目录里生成pow.dll和pow.lib两个文件,其中pow.lib是动态链接库进行静态链接时使用visual studio 2008默认的编译dll的调用约定是cdecl,若用其它程序调用该dll请注意调用约定,否则某些dll中的函数会抛出异常。修改vs2008的调用约定-project-->properties-->configuration properties-->C/C++-->advanced-->calling convention-->选择对应的方式!

     

    三、静态调用Non-MFCdll 

    方式一 

    1、创建一个Win32 Console Application工程,工程名为test1。 

    2、将pow.hpow.dllpow.lib拷贝到F:/c++/test1/test1目录下,把Pow.dll拷贝一份放到F:/c++/test1/Debug目录里防止直接运行exe时找不到dll。 

    3、将pow.h添加到test1工程中 

    4、修改test.Cpp文件如下: 

    #include "stdafx.h" 

    #include <iostream> 

    #include "pow.h"

    #pragma comment(lib,"pow.h")

    using namespace std; 

    int _tmain(int argc, _TCHAR* argv[]) 

    {     char a;  

         cout <<pow(3,3); 

         cin>>a; 

         return 0; 

     方式二 

    1、创建一个Win32 Console Application工程,工程名为test2。 

    2、将pow.dll和pow.lib拷贝到F:/c++/test2/test2目录下,把Pow.dll拷贝一份放到F:/c++/test2/Debug目录下防止直接运行exe时找不到dll。 

    3、新建一个头文件命名为test2.h 

    其文件如下: 

    #pragma comment(lib,"pow.lib") 

    //不使用pragma comment,而直接在工程的Setting->Link页的Object/Moduls栏填入notmfcdll.lib也可 

    __declspec(dllexport) int pow(const int& x,const int& y);  

    4、修改test.Cpp文件如下: 

    #include "stdafx.h" 

    #include "test2.h" 

     int _tmain(int argc, _TCHAR* argv[])

       int a=0; 

       a=pow(3,6); 

       printf("%d",a); 

       char b; 

       b=getchar(); 

         return 0; 

    三、动态调用Non-MFCdll 

    1、创建一个Win32 Console Application工程,工程名为test3。 

    2、将pow.dll拷贝到F:/c++/test3/test3目录下,把Pow.dll拷贝一份放到F:/c++/test/Debug目录下防止直接运行exe时找不到dll。 

    3、修改test3.Cpp文件如下: 

    #include <stdafx.h> 

    #include <stdio.h> 

    #include <windows.h> 

    typedef  int (*MYPROC)( int, int); 

    int _tmain(int argc, _TCHAR* argv[])

    {     int a=0; 

         char b; 

        HINSTANCE hInst;    

         MYPROC  myproc; 

        //加载动态函数库 

        hInst = LoadLibrary(L"pow.dll"); 

         if( hInst != NULL) 

        { 

            myproc = (MYPROC)GetProcAddress( hInst,"pow" );//得到DLL中的函数的指针 

             a=myproc(2,3); 

             printf("%d",a); 

            FreeLibrary(hInst);//卸载DLL

       }

         else

         {

             a=1;

             printf("%d",a);

         }

        b=getchar(); 

         return 0;

    按F5运行程序,抛出异常,调试发现GetProcAddress函数返回为空。 

    因为visual studio 2008编译的dll导出函数是c++格式,而显示调用GetProcAddress函数是按照C格式查找函数,所以需修改pow.h文件,将导出函数包含在extern "C"{}中,如下: 

    extern "C" 

    POW_API int pow(int x, int y);  

    重新编译动态函数,将生成的pow.dll重新拷贝到调用dll的程序中就可以了! 

    导出函数包含在extern "C"{}中,使用静态调用方式二的方法调用该dll时格式也许调整如下: 

    修改头文件test2.h 即可,其文件如下: 

    #pragma comment(lib,"pow.lib")

    展开全文
  • 引子在项目开发过程中,总...一个例子这里以我自己编写的一个VC项目为例,看看删除哪些文件。现在先打开项目工程文件夹,查看项目工程文件夹的大小。可以看到,项目目前大小为119MB,让我们打开看看里面哪些文件

    引子

    在项目开发过程中,总需要从一台电脑上转移代码到另一台电脑上,但是VS的项目动辄好几百M,而这些文件并不是都需要的。那么为了最小文件大小,又可以在另外一台电脑上顺利编译项目,需要携带或者说需要删除项目中的哪些文件呢?

    一个例子

    这里以我自己编写的一个VC项目为例,看看能删除哪些文件。现在先打开项目工程文件夹,查看项目工程文件夹的大小。

    未处理前项目文件夹大小

    可以看到,项目目前大小为119MB,让我们打开看看里面有哪些文件。
    项目文件夹一览

    从这个目录开始说起,这是一个简易的基于wke基于SOUI界面库的浏览器项目。这里对每个项目进行解释:

    • Debug

      Debug文件夹是项目的调试运行文件夹,下图可以看到整个Debug文件夹的内容。
      解决方案Debug文件夹一览

      • MyBrowswer.bsc

      BSCMAKE.EXE 将所有的 SBR 文件作为输入,经过处理之后输出一个BSC文件,在代码导航的时候实际用到的是 BSC 文件。

      可以删除

      • MyBrowser.exe

      如果不执行调试程序,可以删除

      • MyBroser.ilk

      当选定渐增性编译连接时,连接器自动生成 ILK 文件,记录连接信息。

      可以删除

      • MyBrowser.pdb

      全称是 Program DataBase ,即程序数据库文件,用来记录调试信息,是一个相当重要的文件,没有他,程序无法正常调试

      放心吧,可以删除

      • wke.dll

      这是这个项目调用到的动态链接库,理论上也是可以删除的,不过,在转移项目后,也要在此生成它,当然你也可以为了方便起见,不删除

    • localStorage

      这是程序生成的临时文件,当然是可以删除的了

    • MyBrowser

      MyBrowser是项目文件夹,有别于上一层目录的解决方案文件夹,下图是文件夹结构。

      项目文件夹一览

      • controls.extend

      自己定义的扩展类,不能删除

      • Debug

      项目(有别于上一层目录的解决方案的Debug文件夹),可以删除

      • res 、 *.rc 和 uires

      项目资源文件,不能删除

      • third-part

      项目使用到的第三方库,不能删除

      • *.h 和 *.cpp

      代码文件,不能删除

      • MyBrowser.vcxproj

      工程的配置文件,管理工程中细节比如包含的文件,引用等;一般没有sln,也可以直接打开vcxproj,也可以重新生成sln;slin里有多个工程,当你移除某个工程时sln会有变化,sln并不是太重要

      ​ 这个文件不能删除

      • MyBrowser.vcxproj.filters

      用于项目文件的虚拟目录

      ​ 不能删除

      • MyBrowser.vcxproj.user

      用户的一些相关配置

      ​ 不能删除

      • readme.txt

      这个…你想删我也不拦你

    • MyBrowser.sln

      sln文件是管理整个解决方案的,管理多个项目,还是不要删除了

    • MyBrowser.VC.db

      project_name.VC.db 是 sqlite 后端用于 intellisense 的新数据库,它与 VS2015 提供的智能感知、代码恢复、团队本地仓库功能有关,VS重新加载解决方案时速度较快。

      这个文件是可以删除的,并不影响编译项目

    总结

    按照上面所说的一步一步删除不重要的文件,可以发现我们的项目文件夹已经瘦身到了10多M了!同时,打开项目文件夹下的 sln 文件,依然可以成功编译!意味着我们的瘦身之旅达到了目标!

    处理后的文件夹的大小
    另外,需要啰嗦一句的是,这个例子里面并没有出现 ipch 文件夹,需要提醒的是, ipch 文件夹以及 ipch 文件也是可以放心删除的,并且可以节省特别多的大小。
    项目编译过程中会生成很多文件,没事多打开项目工程文件夹看看,也许会有许多意想不到的收获。

    展开全文
  • 另外,该工具还方便地统计出你的工程的规模,可以统计出有几个C文件、几个cpp文件和几个H文件及源程序的行数,使用起来很方便,您不妨下载一个来试试 软件下载网址:http://cppapple.yeah.net ,点击进入“个人...
  • VC建立一个WIN32 DLL 我们利用VC编写DLL有几种方法.如果用VC建立一个WIN32 DLL 工程.那这个工程就应该只导出C++的类或全局变量.和全局函数.方法就是在CPP文件中编写你的代码,为每个需要导出的元素进行导出...
  • VC编写DLL种方法的简介.

    千次阅读 2007-09-25 01:07:00
    VC建立一个WIN32 DLL我们利用VC编写DLL有几种方法.如果用VC建立一个WIN32 DLL 工程.那这个工程就应该只导出C++的类或全局变量.和全局函数.方法就是在CPP文件中编写你的代码,为每个需要导出的元素进行导出办法是...
  • VC6.0是微软1998年发布的,是款很经典的编辑器,然而它有几个很常见的bug,比如, .cpp文件打不开,智能提示出现异常,这里介绍“VC6.0的ClassView里不显示类或成员变量”问题的解决方法。详细步骤如下:  1) ...
  • 我碰到这个问题,一般的解决方法以下几个: 1、忘了将工程调到DEBUG模式,工程在Release模式下,一般是不会进入到断点的。 2、尝试将Debug模式下的目标文件生成目录修改为系统目录。 3、某个文件做了修改,没有...
  • VC6插件系列

    2014-07-01 15:13:55
    功能:此插件是针对C++的一个格式化工具,可以针对自己的编码习惯,选择一种编码风格,也可以自己定义,而且定义非常详细,表达式、指针、模板、类、枚举等十种,肯定满足你的需要。 Numega BoundsChecker...
  • 配置文件的制作,参考了以下处,修改的大概原则是,定义的全定义了,就这样: https://github.com/kahrl/gettext-msvc 这地址提供了libiconv和libintl的VS工程和配置文件。 https://github.com/winlibs 为...
  • 配置文件的制作,参考了以下处,修改的大概原则是,定义的全定义了,就这样: https://github.com/kahrl/gettext-msvc 这地址提供了libiconv和libintl的VS工程和配置文件。 https://github.com/winlibs 为...
  • VC工程的编译原理与过程,将工程中不同的类拆分到不同的原文件中,每一个类由一个.h和.cpp文件共同完成,然后解决头文件重复定义问题,培养了学员良好的编程习惯,也为以后分析MFC Appwizard生成的工程奠定了良好...
  • 用户主要是工业领域的有实力的软件公司或系统集成商,他们对软件的质量要求很高,首先,软件长期处于无人值守的运行状态下,所以,不能有任何隐患出现。其次,图形要及时响应硬件不断发出的指令,所以,反应速度要...
  • VC6上经典的插件

    2013-08-27 17:35:10
    此插件是针对C++的一个格式化工具,可以针对自己的编码习惯,选择一种编码风格,也可以自己定义,而且定义非常详细,表达式、指针、模板、类、枚举等十种,肯定满足你的需要。 6. VC显示行号插件 正确安装...
  • 一个好用的数据库类

    2008-05-14 08:36:06
    新建一个基于对话框的工程,命名为demo1,打开stdafx.h文件,加入#include 从例子中把MyODBC.h,MyODBC.cpp, ODBCSet.h, ODBCSet.cpp复制到这个工程的目录下,并且加入到工程中,方法是菜单project->add to ...
  • vc界面编程经典实例

    2013-03-30 15:36:57
    这篇文章包含一个 demo project,一个继承于 CListCtrl 的类和一个快速查看这个类功能的 release。我 不想让这个类十全十美,但对于我当前的项目来...在一般用 MFC编写的程序的窗口客户区中,可能几个子窗口(具有 W
  • 知识仅局限于能够使用VC 的向导简历一个ATL工程,增加一个ATL简单对象,然后就看到工程里呼啦啦的多了一堆文件IDL,CPP等等,而且编译顺利通过,在别的工程里也可以通过CLSID创建这个类的对象,但是看工程里...
  • 还有一个很大的问题就是“WndTab”提供了很多并不实用(仅仅是本人的看法,如雷同,实属荣幸)而且繁琐、容易出错的功能,比如对标签栏的重组和编号功能,这个功能在频繁地打开和关闭文件时经常令VC的IDE崩溃。...
  • VC LNK2005错误分析

    千次阅读 2014-06-17 14:42:23
    编程中经常遇到LNK2005错误——重复定义错误,其实LNK2005错误并不是一个很难解决的错误。弄清楚它形成的原因,就可以轻松解决它了。 造成LNK2005错误主要以下种情况: 1.重复定义全局变量。可能存在两种...
  • VC PICTURE控件的使用

    热门讨论 2011-04-11 20:12:11
    几个文件是Imgadmin.ocx,Imgcmn.dll,Imgedit.ocx,Imgscan.ocx,Imgshl.dll,Imgthumb.ocx,Imgutil.dll,把它们copy到windows\system目录下,然后用regsvr32.exe将它们分别注册。 2. 打开工程,进入资源管理器...
  • VC:LINK2005错误原理-

    2009-12-01 09:38:00
    编程中经常遇到LNK2005错误——重复定义错误,其实LNK2005错误并不是一个很难解决的错误。弄清楚它形成的原因,就可以轻松解决它了。 造成LNK2005错误主要以下种情况: 1.重复定义全局变量。可能存在两种情况...

空空如也

空空如也

1 2 3 4 5 6
收藏数 118
精华内容 47
关键字:

vc一个工程能有几个文件