当我 link 源文件时,如何修复未定义的宏?
How can I fix a macro not being defined when I link a source file?
问题
我有一个名为“SythConsole.h”的头文件,我在其中定义了预处理器条件语句。
#ifndef UNICODE
#error Please enable unicode for compiler!
#endif
我在主文件中定义了 UNICODE
宏,但是当我 link 源文件(“SythConsole.cpp”)并编译时。我收到一条错误消息,告诉我 UNICODE
尚未在我的主文件中定义。如何 link 源文件对象与主文件对象?
错误:
#error Please enable unicode for compiler!
发生另一个错误(参数太少):
C:\Programming\C++\Libraries\windowEngine\main.cpp:45:48: error: no matching function for call to 'Syth::consoleWindow::ConstructConsole(int, int, int, int, const wchar_t [5])'
window.ConstructConsole(100,100,8,8,L"Test");
C:\Programming\C++\Libraries\windowEngine\include/SythConsole.h:51:17: note: candidate: 'int Syth::consoleWindow::ConstructConsole(int, int, int, int, std::__cxx11::wstring, bool)'
int ConstructConsole(int width, int height, int fontW, int fontH, std::wstring t_winName, bool t_CursorVis);
我不知道为什么会出现这个错误,因为 t_CursorVis
有一个默认参数。
我试过的
我试过不 link 源文件并从主文件编译所有内容,我将 #include SythConsole.cpp
放在头文件的底部。此更改的结果允许我编译并且没有抛出任何错误。
信息和源代码
我的编译命令:
g++ main.cpp src/SythConsole.cpp -o main.exe
我的工作区:
- 包括
- SythConsole.h
- 来源
- SythConsole.cpp
- main.cpp
main.cpp源代码:
#define UNICODE
#include "include/SythConsole.h"
int main()
{
Syth::consoleWindow window;
window.ConstructConsole(100,100,8,8,L"Test");
while (true)
{
/* code */
}
}
SythConsole.cpp:
#include "../include/SythConsole.h"
//Protected
namespace Syth
{
int consoleWindow::MakeError(const wchar_t *msg)
{
wchar_t buffer[256]; // Buffer for containing the error message
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, 256, NULL); // Format the Error message from GetLastError()
SetConsoleActiveScreenBuffer(m_hConsoleOrgi); // Set the screen buffer to the intial screen buffer so the error can be displayed without any interference from the current buffer
std::wcout << "Error: " << msg << " " << buffer << std::endl;
return 0;
}
// Public
consoleWindow::consoleWindow() : m_ScreenWidth(80), m_ScreenHeight(30), m_MouseX(0), m_MouseY(0), m_WinName(L"Console"), m_CursorVis(false)
{
m_hConsoleOrgi = GetStdHandle(STD_OUTPUT_HANDLE);
m_hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
m_hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
}
int consoleWindow::ConstructConsole(int width, int height, int fontW, int fontH, std::wstring t_winName = L"Console", bool t_CursorVis = false)
{
if (m_hConsole == INVALID_HANDLE_VALUE)
return MakeError(L"INVALID HANDLE");
m_ScreenWidth = width;
m_ScreenHeight = height;
m_WinName = t_winName;
m_RectWindow = {0, 0, 1, 1};
SetConsoleWindowInfo(m_hConsole, TRUE, &m_RectWindow);
COORD xyCoord { (short)m_ScreenWidth, (short)m_ScreenHeight };
if (!SetConsoleScreenBufferSize(m_hConsole, xyCoord))
return MakeError(L"SetConsoleScreenBufferSize");
if (!SetConsoleActiveScreenBuffer(m_hConsole))
return MakeError(L"SetConsoleActiveScreenBuffer");
CONSOLE_FONT_INFOEX cfi;
cfi.cbSize = sizeof(cfi);
cfi.nFont = 0;
cfi.dwFontSize.X = fontW;
cfi.dwFontSize.Y = fontH;
cfi.FontFamily = FF_DONTCARE;
cfi.FontWeight = FW_NORMAL;
wcscpy_s(cfi.FaceName, L"Terminal");
if (!SetCurrentConsoleFontEx(m_hConsole, false,&cfi))
return MakeError(L"SetCurrentConsoleFontEx");
CONSOLE_SCREEN_BUFFER_INFO csbi;
// Check if the size given by the programmer is bigger than the screen buffer
if (!GetConsoleScreenBufferInfo(m_hConsole,&csbi))
return MakeError(L"GetConsoleScreenBufferInfo");
if (m_ScreenHeight > csbi.dwMaximumWindowSize.Y)
return MakeError(L"Screen Height is too big");
if (m_ScreenWidth > csbi.dwMaximumWindowSize.X)
return MakeError(L"Screen Width is too big");
short tempWidth = m_ScreenWidth-1;
short tempHeight = m_ScreenHeight-1;
m_RectWindow = {0, 0, tempWidth, tempHeight};
// Changes the dimensions of the Window
if (!SetConsoleWindowInfo(m_hConsole, TRUE, &m_RectWindow))
return MakeError(L"SetConsoleWindowInfo");
if (!SetConsoleMode(m_hConsoleIn, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS))
return MakeError(L"SetConsoleMode");
wchar_t title[256];
swprintf(title,256,m_WinName.c_str());
SetConsoleTitle(title);
CONSOLE_CURSOR_INFO cci;
if (!GetConsoleCursorInfo(m_hConsole, &cci))
return MakeError(L"GetConsoleCursorInfo");
cci.bVisible = t_CursorVis;
m_CursorVis = t_CursorVis;
if (!SetConsoleCursorInfo(m_hConsole,&cci))
return MakeError(L"SetCnsoleCursorInfo");
// Create the screen buffer that stores data to be displayed on screen
m_ScreenBuf = new CHAR_INFO[m_ScreenWidth*m_ScreenHeight];
memset(m_ScreenBuf, 0, sizeof(CHAR_INFO)*m_ScreenHeight*m_ScreenWidth); // Sets all the unintialized
return 1;
}
int consoleWindow::getWidth() const { return m_ScreenWidth; }
int consoleWindow::getHeight() const { return m_ScreenHeight; }
int consoleWindow::getMouseX() const { return m_MouseX; }
int consoleWindow::getMouseY() const { return m_MouseY; }
void consoleWindow::handleMouseEvent(INPUT_RECORD &t_Record)
{
switch (t_Record.Event.MouseEvent.dwEventFlags)
{
case MOUSE_MOVED:
m_MouseX = t_Record.Event.MouseEvent.dwMousePosition.X;
m_MouseY = t_Record.Event.MouseEvent.dwMousePosition.Y;
break;
default:
break;
}
}
void consoleWindow::updateInputEvents()
{
DWORD numEvents {0};
GetNumberOfConsoleInputEvents(m_hConsoleIn, &numEvents);
if (numEvents == 0)
return;
INPUT_RECORD recordBuf[128];
ReadConsoleInput(m_hConsoleIn,recordBuf, numEvents, &numEvents);
for (DWORD i {0}; i < numEvents; i++)
{
switch (recordBuf[i].EventType)
{
case MOUSE_EVENT:
handleMouseEvent(recordBuf[i]);
break;
default:
break;
}
}
}
void consoleWindow::clip(int &t_X, int &t_Y)
{
if (t_X < 0) t_X = 0;
if (t_X >= m_ScreenWidth) t_X = m_ScreenWidth;
if (t_Y < 0) t_Y = 0;
if (t_Y >= m_ScreenHeight) t_Y = m_ScreenHeight;
}
void consoleWindow::draw(int t_X, int t_Y, short t_Char, short t_Attribute)
{
if (t_X >= 0 && t_X <= m_ScreenWidth && t_Y >= 0 && t_Y <= m_ScreenHeight)
{
m_ScreenBuf[m_ScreenWidth * t_Y + t_X].Char.UnicodeChar = t_Char;
m_ScreenBuf[m_ScreenWidth * t_Y + t_X].Attributes = t_Attribute;
}
}
void consoleWindow::fill(Syth::coord t_Start, Syth::coord t_End, short t_Char, short t_Attribute)
{
for (int i {t_Start.x}; i <= t_End.x; i++)
{
for (int z {t_Start.y}; z <= t_End.y; z++)
{
draw(i,z,t_Char,t_Attribute);
}
}
}
void consoleWindow::drawString(int t_X, int t_Y, std::wstring t_String, short t_Attribute)
{
for (int i {0}, width {t_X}; i < t_String.size(); i++, width++)
{
draw(width,t_Y,t_String.at(i), t_Attribute);
}
}
void consoleWindow::drawTriangle(coord vertex1, coord vertex2, coord vertex3, short t_Char, short t_Attribute)
{
drawLine(vertex1, vertex2 ,t_Char, t_Attribute);
drawLine(vertex2, vertex3, t_Char, t_Attribute);
drawLine(vertex3, vertex1, t_Char, t_Attribute);
}
void consoleWindow::drawLine(coord t_p1, coord t_p2, short t_Char, short t_Attribute)
{
float slope = 0.0f;
if (t_p1.x != t_p2.x)
slope = ((float)t_p2.y - (float)t_p1.y) / ((float)t_p2.x - (float)t_p1.x);
if (t_p1.x != t_p2.x && abs(slope) <= 1.0f)
{
if (t_p1.x > t_p2.x)
std::swap(t_p1, t_p2);
float c {t_p1.y - slope*t_p1.x};
for (int i {t_p1.x}; i < t_p2.x; i++)
{
int bufferY = slope * i + c;
draw(i,bufferY, t_Char, t_Attribute);
}
}
else
{
if (t_p1.y > t_p2.y)
std::swap(t_p1, t_p2);
float slopeY { ((float)t_p1.x - (float)t_p2.x) / ((float)t_p1.y - (float)t_p2.y)};
float cY {t_p1.x - slopeY*t_p1.y};
for (int i {t_p1.y}; i < t_p2.y; i++)
{
int bufferX = slopeY * i + cY;
draw(bufferX, i, t_Char, t_Attribute);
}
}
}
void consoleWindow::renderQuad(Syth::coord vertex1,Syth::coord vertex2, Syth::coord vertex3, Syth::coord vertex4, short t_Char, short t_Attribute)
{
drawLine(vertex1, vertex2, t_Char, t_Attribute);
drawLine(vertex1, vertex3, t_Char, t_Attribute);
drawLine(vertex1, vertex4, t_Char, t_Attribute);
drawLine(vertex2, vertex3, t_Char, t_Attribute);
drawLine(vertex2, vertex4, t_Char, t_Attribute);
drawLine(vertex3, vertex4, t_Char, t_Attribute);
}
void consoleWindow::clear()
{
memset(m_ScreenBuf, 0, sizeof(CHAR_INFO)*m_ScreenHeight*m_ScreenWidth);
}
void consoleWindow::update()
{
short tempW = m_ScreenWidth;
short tempH = m_ScreenHeight;
WriteConsoleOutput(m_hConsole,m_ScreenBuf, {tempW, tempH}, {0,0}, &m_RectWindow);
}
consoleWindow::~consoleWindow()
{
delete [] m_ScreenBuf;
}
}
SythConsole.h源代码:
#pragma once
#ifndef UNICODE
#error Please enable unicode for compiler!
#endif
#include <string>
#include <windows.h>
#include <iostream>
#include <cmath>
#include <vector>
#include "SythColour.h"
#include "SythKeyMap.h"
#include "SythUtilities.h"
namespace Syth
{
class consoleWindow
{
protected:
int m_ScreenWidth;
int m_ScreenHeight;
int m_MouseX;
int m_MouseY;
std::wstring m_WinName;
CHAR_INFO *m_ScreenBuf;
SMALL_RECT m_RectWindow;
bool m_CursorVis;
HANDLE m_hConsole;
HANDLE m_hConsoleIn;
HANDLE m_hConsoleOrgi;
protected:
int MakeError(const wchar_t *msg);
void handleMouseEvent(INPUT_RECORD &t_Record);
public:
consoleWindow();
~consoleWindow();
public:
int ConstructConsole(int width, int height, int fontW, int fontH, std::wstring t_winName, bool t_CursorVis);
int getWidth() const;
int getHeight() const;
int getMouseX() const;
int getMouseY() const;
void updateInputEvents();
void clip(int &t_X, int &t_Y);
void draw (int t_X, int t_Y, short t_Char, short t_Attribute);
void fill(coord t_Start, coord t_End, short t_Char, short t_Attribute);
void drawString(int t_X, int t_Y, std::wstring t_String, short t_Attribute);
void drawLine(coord t_p1, coord t_p2, short t_Char, short t_Attribute);
void renderQuad(coord vertex1,coord vertex2, coord vertex3, coord vertex4, short t_Char, short t_Attribute);
void drawTriangle(coord vertex1, coord vertex2, coord vertex3, short t_Char, short t_Attribute);
void clear();
void update();
};
}
预处理器宏对于每个翻译单元都是本地的。 main.cpp 中的宏定义无法在 SythConsole.cpp 中看到。
如果 SythConsole.h 要求定义 UNICODE,那么您必须在包含 header.
的所有翻译单元中定义该宏
如果一个宏需要在所有翻译单元中定义,那么您不应该在源代码中定义它,而是在调用编译器时定义它。
How can I link the source file with the main file?
源文件未链接。链接是用 object 文件完成的,这些文件是编译翻译单元的结果。您使用的编译器命令正确链接编译后的程序。
但是链接与涉及宏的问题无关。预处理器宏由预处理器处理,预处理发生在编译之前(或者可以看作是 sub-step 编译),而链接发生在编译之后。
问题
我有一个名为“SythConsole.h”的头文件,我在其中定义了预处理器条件语句。
#ifndef UNICODE
#error Please enable unicode for compiler!
#endif
我在主文件中定义了 UNICODE
宏,但是当我 link 源文件(“SythConsole.cpp”)并编译时。我收到一条错误消息,告诉我 UNICODE
尚未在我的主文件中定义。如何 link 源文件对象与主文件对象?
错误:
#error Please enable unicode for compiler!
发生另一个错误(参数太少):
C:\Programming\C++\Libraries\windowEngine\main.cpp:45:48: error: no matching function for call to 'Syth::consoleWindow::ConstructConsole(int, int, int, int, const wchar_t [5])' window.ConstructConsole(100,100,8,8,L"Test");
C:\Programming\C++\Libraries\windowEngine\include/SythConsole.h:51:17: note: candidate: 'int Syth::consoleWindow::ConstructConsole(int, int, int, int, std::__cxx11::wstring, bool)' int ConstructConsole(int width, int height, int fontW, int fontH, std::wstring t_winName, bool t_CursorVis);
我不知道为什么会出现这个错误,因为 t_CursorVis
有一个默认参数。
我试过的
我试过不 link 源文件并从主文件编译所有内容,我将 #include SythConsole.cpp
放在头文件的底部。此更改的结果允许我编译并且没有抛出任何错误。
信息和源代码
我的编译命令:
g++ main.cpp src/SythConsole.cpp -o main.exe
我的工作区:
- 包括
- SythConsole.h
- 来源
- SythConsole.cpp
- main.cpp
main.cpp源代码:
#define UNICODE
#include "include/SythConsole.h"
int main()
{
Syth::consoleWindow window;
window.ConstructConsole(100,100,8,8,L"Test");
while (true)
{
/* code */
}
}
SythConsole.cpp:
#include "../include/SythConsole.h"
//Protected
namespace Syth
{
int consoleWindow::MakeError(const wchar_t *msg)
{
wchar_t buffer[256]; // Buffer for containing the error message
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, 256, NULL); // Format the Error message from GetLastError()
SetConsoleActiveScreenBuffer(m_hConsoleOrgi); // Set the screen buffer to the intial screen buffer so the error can be displayed without any interference from the current buffer
std::wcout << "Error: " << msg << " " << buffer << std::endl;
return 0;
}
// Public
consoleWindow::consoleWindow() : m_ScreenWidth(80), m_ScreenHeight(30), m_MouseX(0), m_MouseY(0), m_WinName(L"Console"), m_CursorVis(false)
{
m_hConsoleOrgi = GetStdHandle(STD_OUTPUT_HANDLE);
m_hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
m_hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
}
int consoleWindow::ConstructConsole(int width, int height, int fontW, int fontH, std::wstring t_winName = L"Console", bool t_CursorVis = false)
{
if (m_hConsole == INVALID_HANDLE_VALUE)
return MakeError(L"INVALID HANDLE");
m_ScreenWidth = width;
m_ScreenHeight = height;
m_WinName = t_winName;
m_RectWindow = {0, 0, 1, 1};
SetConsoleWindowInfo(m_hConsole, TRUE, &m_RectWindow);
COORD xyCoord { (short)m_ScreenWidth, (short)m_ScreenHeight };
if (!SetConsoleScreenBufferSize(m_hConsole, xyCoord))
return MakeError(L"SetConsoleScreenBufferSize");
if (!SetConsoleActiveScreenBuffer(m_hConsole))
return MakeError(L"SetConsoleActiveScreenBuffer");
CONSOLE_FONT_INFOEX cfi;
cfi.cbSize = sizeof(cfi);
cfi.nFont = 0;
cfi.dwFontSize.X = fontW;
cfi.dwFontSize.Y = fontH;
cfi.FontFamily = FF_DONTCARE;
cfi.FontWeight = FW_NORMAL;
wcscpy_s(cfi.FaceName, L"Terminal");
if (!SetCurrentConsoleFontEx(m_hConsole, false,&cfi))
return MakeError(L"SetCurrentConsoleFontEx");
CONSOLE_SCREEN_BUFFER_INFO csbi;
// Check if the size given by the programmer is bigger than the screen buffer
if (!GetConsoleScreenBufferInfo(m_hConsole,&csbi))
return MakeError(L"GetConsoleScreenBufferInfo");
if (m_ScreenHeight > csbi.dwMaximumWindowSize.Y)
return MakeError(L"Screen Height is too big");
if (m_ScreenWidth > csbi.dwMaximumWindowSize.X)
return MakeError(L"Screen Width is too big");
short tempWidth = m_ScreenWidth-1;
short tempHeight = m_ScreenHeight-1;
m_RectWindow = {0, 0, tempWidth, tempHeight};
// Changes the dimensions of the Window
if (!SetConsoleWindowInfo(m_hConsole, TRUE, &m_RectWindow))
return MakeError(L"SetConsoleWindowInfo");
if (!SetConsoleMode(m_hConsoleIn, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS))
return MakeError(L"SetConsoleMode");
wchar_t title[256];
swprintf(title,256,m_WinName.c_str());
SetConsoleTitle(title);
CONSOLE_CURSOR_INFO cci;
if (!GetConsoleCursorInfo(m_hConsole, &cci))
return MakeError(L"GetConsoleCursorInfo");
cci.bVisible = t_CursorVis;
m_CursorVis = t_CursorVis;
if (!SetConsoleCursorInfo(m_hConsole,&cci))
return MakeError(L"SetCnsoleCursorInfo");
// Create the screen buffer that stores data to be displayed on screen
m_ScreenBuf = new CHAR_INFO[m_ScreenWidth*m_ScreenHeight];
memset(m_ScreenBuf, 0, sizeof(CHAR_INFO)*m_ScreenHeight*m_ScreenWidth); // Sets all the unintialized
return 1;
}
int consoleWindow::getWidth() const { return m_ScreenWidth; }
int consoleWindow::getHeight() const { return m_ScreenHeight; }
int consoleWindow::getMouseX() const { return m_MouseX; }
int consoleWindow::getMouseY() const { return m_MouseY; }
void consoleWindow::handleMouseEvent(INPUT_RECORD &t_Record)
{
switch (t_Record.Event.MouseEvent.dwEventFlags)
{
case MOUSE_MOVED:
m_MouseX = t_Record.Event.MouseEvent.dwMousePosition.X;
m_MouseY = t_Record.Event.MouseEvent.dwMousePosition.Y;
break;
default:
break;
}
}
void consoleWindow::updateInputEvents()
{
DWORD numEvents {0};
GetNumberOfConsoleInputEvents(m_hConsoleIn, &numEvents);
if (numEvents == 0)
return;
INPUT_RECORD recordBuf[128];
ReadConsoleInput(m_hConsoleIn,recordBuf, numEvents, &numEvents);
for (DWORD i {0}; i < numEvents; i++)
{
switch (recordBuf[i].EventType)
{
case MOUSE_EVENT:
handleMouseEvent(recordBuf[i]);
break;
default:
break;
}
}
}
void consoleWindow::clip(int &t_X, int &t_Y)
{
if (t_X < 0) t_X = 0;
if (t_X >= m_ScreenWidth) t_X = m_ScreenWidth;
if (t_Y < 0) t_Y = 0;
if (t_Y >= m_ScreenHeight) t_Y = m_ScreenHeight;
}
void consoleWindow::draw(int t_X, int t_Y, short t_Char, short t_Attribute)
{
if (t_X >= 0 && t_X <= m_ScreenWidth && t_Y >= 0 && t_Y <= m_ScreenHeight)
{
m_ScreenBuf[m_ScreenWidth * t_Y + t_X].Char.UnicodeChar = t_Char;
m_ScreenBuf[m_ScreenWidth * t_Y + t_X].Attributes = t_Attribute;
}
}
void consoleWindow::fill(Syth::coord t_Start, Syth::coord t_End, short t_Char, short t_Attribute)
{
for (int i {t_Start.x}; i <= t_End.x; i++)
{
for (int z {t_Start.y}; z <= t_End.y; z++)
{
draw(i,z,t_Char,t_Attribute);
}
}
}
void consoleWindow::drawString(int t_X, int t_Y, std::wstring t_String, short t_Attribute)
{
for (int i {0}, width {t_X}; i < t_String.size(); i++, width++)
{
draw(width,t_Y,t_String.at(i), t_Attribute);
}
}
void consoleWindow::drawTriangle(coord vertex1, coord vertex2, coord vertex3, short t_Char, short t_Attribute)
{
drawLine(vertex1, vertex2 ,t_Char, t_Attribute);
drawLine(vertex2, vertex3, t_Char, t_Attribute);
drawLine(vertex3, vertex1, t_Char, t_Attribute);
}
void consoleWindow::drawLine(coord t_p1, coord t_p2, short t_Char, short t_Attribute)
{
float slope = 0.0f;
if (t_p1.x != t_p2.x)
slope = ((float)t_p2.y - (float)t_p1.y) / ((float)t_p2.x - (float)t_p1.x);
if (t_p1.x != t_p2.x && abs(slope) <= 1.0f)
{
if (t_p1.x > t_p2.x)
std::swap(t_p1, t_p2);
float c {t_p1.y - slope*t_p1.x};
for (int i {t_p1.x}; i < t_p2.x; i++)
{
int bufferY = slope * i + c;
draw(i,bufferY, t_Char, t_Attribute);
}
}
else
{
if (t_p1.y > t_p2.y)
std::swap(t_p1, t_p2);
float slopeY { ((float)t_p1.x - (float)t_p2.x) / ((float)t_p1.y - (float)t_p2.y)};
float cY {t_p1.x - slopeY*t_p1.y};
for (int i {t_p1.y}; i < t_p2.y; i++)
{
int bufferX = slopeY * i + cY;
draw(bufferX, i, t_Char, t_Attribute);
}
}
}
void consoleWindow::renderQuad(Syth::coord vertex1,Syth::coord vertex2, Syth::coord vertex3, Syth::coord vertex4, short t_Char, short t_Attribute)
{
drawLine(vertex1, vertex2, t_Char, t_Attribute);
drawLine(vertex1, vertex3, t_Char, t_Attribute);
drawLine(vertex1, vertex4, t_Char, t_Attribute);
drawLine(vertex2, vertex3, t_Char, t_Attribute);
drawLine(vertex2, vertex4, t_Char, t_Attribute);
drawLine(vertex3, vertex4, t_Char, t_Attribute);
}
void consoleWindow::clear()
{
memset(m_ScreenBuf, 0, sizeof(CHAR_INFO)*m_ScreenHeight*m_ScreenWidth);
}
void consoleWindow::update()
{
short tempW = m_ScreenWidth;
short tempH = m_ScreenHeight;
WriteConsoleOutput(m_hConsole,m_ScreenBuf, {tempW, tempH}, {0,0}, &m_RectWindow);
}
consoleWindow::~consoleWindow()
{
delete [] m_ScreenBuf;
}
}
SythConsole.h源代码:
#pragma once
#ifndef UNICODE
#error Please enable unicode for compiler!
#endif
#include <string>
#include <windows.h>
#include <iostream>
#include <cmath>
#include <vector>
#include "SythColour.h"
#include "SythKeyMap.h"
#include "SythUtilities.h"
namespace Syth
{
class consoleWindow
{
protected:
int m_ScreenWidth;
int m_ScreenHeight;
int m_MouseX;
int m_MouseY;
std::wstring m_WinName;
CHAR_INFO *m_ScreenBuf;
SMALL_RECT m_RectWindow;
bool m_CursorVis;
HANDLE m_hConsole;
HANDLE m_hConsoleIn;
HANDLE m_hConsoleOrgi;
protected:
int MakeError(const wchar_t *msg);
void handleMouseEvent(INPUT_RECORD &t_Record);
public:
consoleWindow();
~consoleWindow();
public:
int ConstructConsole(int width, int height, int fontW, int fontH, std::wstring t_winName, bool t_CursorVis);
int getWidth() const;
int getHeight() const;
int getMouseX() const;
int getMouseY() const;
void updateInputEvents();
void clip(int &t_X, int &t_Y);
void draw (int t_X, int t_Y, short t_Char, short t_Attribute);
void fill(coord t_Start, coord t_End, short t_Char, short t_Attribute);
void drawString(int t_X, int t_Y, std::wstring t_String, short t_Attribute);
void drawLine(coord t_p1, coord t_p2, short t_Char, short t_Attribute);
void renderQuad(coord vertex1,coord vertex2, coord vertex3, coord vertex4, short t_Char, short t_Attribute);
void drawTriangle(coord vertex1, coord vertex2, coord vertex3, short t_Char, short t_Attribute);
void clear();
void update();
};
}
预处理器宏对于每个翻译单元都是本地的。 main.cpp 中的宏定义无法在 SythConsole.cpp 中看到。
如果 SythConsole.h 要求定义 UNICODE,那么您必须在包含 header.
的所有翻译单元中定义该宏如果一个宏需要在所有翻译单元中定义,那么您不应该在源代码中定义它,而是在调用编译器时定义它。
How can I link the source file with the main file?
源文件未链接。链接是用 object 文件完成的,这些文件是编译翻译单元的结果。您使用的编译器命令正确链接编译后的程序。
但是链接与涉及宏的问题无关。预处理器宏由预处理器处理,预处理发生在编译之前(或者可以看作是 sub-step 编译),而链接发生在编译之后。