写人两笔,做人一生
2010-06-06 18:10
113 查看
原文及更多内容,在这里:http://yysource.sourceforge.net/?p=66
创建DLL:
新建DLL工程:
在VC6下,File —> New —> Projects —> Win32 Dynamic-Link Library(一般在倒数第二个)—> 输入名字 —> 选择 An empty DLL project. —> Finish
新建头文件:
File —> New —> Files —> C/C++ Header File我的头文件是:ErrTest.h
/*************************************************************************** Module: ErrTest.h ***************************************************************************/ #ifndef ERRTEST_H #define ERRTEST_H // 该宏定义在(VC6.0下)工程属性--> C/C++ --> project options 中由系统默认定义 // 所以同一个DLL工程引用此头文件时,就不用手工定义 ERRTEST_EXPORTS 了 #ifdef ERRTEST_EXPORTS #define ERRTESTAPI __declspec(dllexport) // 当此头文件被DLL中的源代码模块引用时定义 #else #define ERRTESTAPI __declspec(dllimport) // 当此头文件被其他工程中的源代码模块引用时定义 #endif class ERRTESTAPI ErrTest { // ERRTESTAPI 不是放在 class 左边! public: static void printf(const char *fmt, ...); static HANDLE GetConsole(int nStdHandle = STD_OUTPUT_HANDLE); static HANDLE hConsole; }; ERRTESTAPI extern int nErrTest; // 要加 extern ERRTESTAPI void func(void); #endif ////////////////////////////// End of File /////////////////////////////////
新建源文件:
File —> New —> Files —> C++ Source File我的源文件是:ErrTest.cpp
/*************************************************************************** Module: ErrTest.cpp ***************************************************************************/ #include <windows.h> #include <stdio.h> #include <exception> #include <stdarg.h> #include "ErrTest.h" HANDLE ErrTest::hConsole = NULL; int nErrTest = 5; // 把格式化字符串输出到控制台窗口中 void ErrTest::printf(const char *fmt, ...) { const int BUFSIZE = 65535; int sz; // const char *p; char szBuf[BUFSIZE]; GetConsole(); va_list valist; // p = fmt+strlen(fmt)-1; va_start(valist, fmt); // vsprintf(szBuf, fmt, valist); vsprintf(szBuf, fmt, valist); va_end(valist); sz = strlen(szBuf)*sizeof(char); __try { WriteConsole(GetConsole(), szBuf, sz, NULL, NULL); } __except (EXCEPTION_EXECUTE_HANDLER) { int e = GetLastError(); MessageBox(NULL, TEXT("Error in ErrTest::printf when WriteConsole()!"), 0, 0); } } // 获取控制台句柄,默认返回的是输出用的句柄。 HANDLE ErrTest::GetConsole(int nStdHandle /* = STD_OUTPUT_HANDLE */) { if (hConsole == NULL) { AllocConsole(); hConsole = GetStdHandle(nStdHandle); // hConsole = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, // FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); } return hConsole; } void func() { MessageBox(0, "errtest.cpp 00", 0, 0); }
生成DLL文件:
Build(或F7)之后,会发现在 Debug 文件夹下有 ErrTest.lib 和 ErrTest.dll 两个文件,加上 ErrTest.h,就是此次工程生成的最主要的三个文件了。创建示例用的可运行文件:
File —> New —> Win32 Application —> A typical "Hello World!" application —> Finish按如下代码中中文所示部分,加入适当的内容:
// 1.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "resource.h" #include "ErrTest.h" // 《《———— 加入头文件 #pragma comment(lib, "ErrTest.lib") // 《《———— 告诉链接器要加载lib文件 #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text // Foward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. ErrTest::printf("ErrTest::printf(): %d", nErrTest); // 《《———— 调用DLL中的类静态成员和全局变量 func(); // 《《———— 调用DLL函数 MSG msg; HACCEL hAccelTable;
然后,将刚才创建DLL之后产生的 ErrTest.h 头文件、ErrTest.lib、ErrTest.dll文件复制到示例工程.dsw所在文件夹中。按Ctrl+F5即可运行得到结果。
注意:
1.必须通知链接器加载 lib 文件,如果链接器无法加载此文件,那么在工程中引用的所有变量、函数都会出现 unresolved external symbol 的错误,如下:--------------------Configuration: 1 - Win32 Debug-------------------- Compiling... 1.cpp Linking... 1.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl func(void)" (__imp_?func@@YAXXZ) 1.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: static void __cdecl ErrTest::printf(char const *,...)" (__imp_?printf@ErrTest@@SAXPBDZZ) 1.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) int nErrTest" (__imp_?nErrTest@@3HA) Debug/1.exe : fatal error LNK1120: 3 unresolved externals Error executing link.exe. 1.exe - 4 error(s), 0 warning(s)
那么,通知链接器(linker)去加载lib的方法有两种,一种就是如上所示,在源代码中添加 #pragma comment(lib, "ErrTest.lib"),这里要注意,#pragma 不是 #progma!另一种,就是在 Project —> settings —> link选项卡 —> Object/library modules 中加入 ErrTest.lib 。
2.DLL 和 lib 和 头文件,都不一定要与exe文件在同一目录,可以放在系统环境变量 PATH(或者再加上 include、lib)中有记录的任何地方。
原文及更多内容,在这里:http://yysource.sourceforge.net/?p=66
相关文章推荐
- 写人两笔,做人一生
- 写人两笔 做人一生
- 一生致命的8个经典问题:做人何必那么执著
- 做事一件,做人一生!
- 受用一生的做人处世36字诀
- 一生中的八个经典问题--做人你不能不知道
- 一生学做人
- 一生中的八个经典问题--做人你不能不知道
- 一生致命的8个经典问题:做人何必那么执著
- 一生学做人
- 做人处事学问真不少:36字诀窍受用你一生!
- 人的一生最后悔什么?——曾获各界名流都认同的忠告!
- 唐骏“学历门”的感悟 低调做人踏实做事
- 做人的心计
- 七个受用一生的心理寓言
- 毕业五年决定你的一生
- 做人的基本礼仪,绝对让你受益非浅
- [幸福篇HAPPINESS]Learn with whole Life 一生的学习
- 读书-看人-做人
- 引用 七个受用一生的心理寓言(转)