Skip to content

Latest commit

 

History

History
135 lines (100 loc) · 5.01 KB

File metadata and controls

135 lines (100 loc) · 5.01 KB

环境配置 与 Hello LibGraphics

LibGraphics是只面向Windows的图形库,因此本项目使用朴实无华的Visual Studio进行开发。C大程授课一般使用VS 2010版本,但由于笔者懒得去下载旧版,就用手头的VS 2019。

VS 2019要跑起LibGraphics来还是需要一番配置的。

  • 打开VS 2019,创建一个空的C/C++项目

  • 刘新国老师维护的LibGraphics下载到本地,将其中的libgraphics文件夹复制到项目在磁盘的根目录下。

  • 在VS 2019 的 解决方案资源管理器 - <项目名>/源文件 中,添加一个筛选器(就是虚拟的文件夹),命名为libgraphics

  • 对 <项目名>/源文件/libgraphics 右键,添加现有项,将libgraphics文件夹(在磁盘的项目根目录下)中所有的**.c后缀**文件添加进来。

  • 对 <项目名>/源文件/libgraphics 右键,添加新建项,添加一个main.c文件。

  • 以上步骤之后,磁盘中的项目根目录如下:

+ <项目名>
|__+ libragphics
|  |__ graphics.h
|  |__ graphics.c
|  |__ ...
|__ main.c
|__ <项目名>.sln
|__ <项目名>.vcxproj
|__ ...
  • VS 2019中的解决方案资源管理器如下:
+ <项目名>
|__+ 头文件
|__+ 源文件
|  |__ main.c
|  |__+ libgraphics
|     |__ graphics.c
|     |__ genlib.c
|     |__ ...
|__ ...
  • main.c中输入以下代码:
#include "libgraphics/extgraph.h"

void Main()
{
	InitGraphics();
	SetWindowTitle("Hello LibGraphics");
	MovePen(0, 0);
	DrawLine(5, 5);
} 
  • 按F5编译并调试,肯定会输出如下错误:

    • C4996 ......This function or variable may be unsafe. Consider using <***> instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

  • 参考错误提示信息,对VS 2019的 解决方案资源管理器 - <项目名> 右键,进入 属性,在 配置属性 - C/C++ - 预处理器 中,为预处理器定义栏添加**_CRT_SECURE_NO_WARNINGS**。

  • 按F5编译并调试,之前的错误已经消失,但肯定会输出如下错误:

    • LNK2019 无法解析的外部符号 _main,函数 "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) 中引用了该符号

  • 参考链接器工具错误 LNK2019 | Microsoft Docs,同上进入项目的属性配置窗口,将 配置属性 - 链接器 - 系统 的子系统选项从控制台改成窗口

  • 按F5编译并调试,之前的错误已经消失,但可能会输出如下错误:

    • 由于找不到<***>.dll,无法继续执行代码,......

  • 根据笔者的经验(Doge),同上进入项目的属性配置窗口,将 配置属性 - C/C++ - 代码生成 的运行库多线程调试(MDd)改成多线程(MD)

  • 按F5编译并调试,终于看到窗口弹出来了,其中有一条直线。这就是我们的Hello LibGraphics程序,用于验证开发环境的完整性。

  • 虽然如此,但窗口标题是乱码令人不爽。Debug发现是经典的字符集问题。

    • Debug过程,一路F12寻找符号的定义:
// main.c
SetWindowTitle("Hello LibGraphics"); // 对它【按F12】
// ||
// \/
// extgraph.h
void SetWindowTitle(string title)
{
    windowTitle = CopyString(title);
    if (initialized) {
        SetWindowText(graphicsWindow, windowTitle); // 对它【按F12】
    }
}
// ||
// \/
// WinUser.h
BOOL
WINAPI
SetWindowTextA(
    _In_ HWND hWnd,
    _In_opt_ LPCSTR lpString);
WINUSERAPI
BOOL
WINAPI
SetWindowTextW(
    _In_ HWND hWnd,
    _In_opt_ LPCWSTR lpString);
#ifdef UNICODE // 发现UNICODE宏被定义,调用SetWindowTextW,因此对其参数2 LPCWSTR 【按F12】
#define SetWindowText  SetWindowTextW
#else
#define SetWindowText  SetWindowTextA
#endif // !UNICODE
// ||
// \/
// winnt.h
typedef _Null_terminated_ CONST WCHAR *LPCWSTR, *PCWSTR; // WCHAR发现!
  • 可以看到,由于UNICODE宏被定义,最终调用的是SetWindowTextW(一个WIN32的API),使用的参数是面向Unicode字符集WCHAR,而LibGraphics使用的string(实际上是char*类型)只支持ASCⅡ字符集,我们传入的**"Hello LibGraphics"**也都是纯纯的ASCⅡ字符。

    • 得出最简单的解决方法:把UNICODE宏的定义取消!那这个宏定义在哪呢?
    • UNICODE宏按F12,VS 2019报告“找不到宏定义”。
      • 既然不在代码中定义,那肯定在预处理阶段定义了
    • 同上进入项目的属性配置窗口,查看 配置属性 - C/C++ 的预处理器定义栏,发现没有UNICODE。
    • 根据笔者的经验(Doge),查看 配置属性 - 高级,发现字符集选项为使用UNICODE字符集,将其改成未设置,问题解决!