在我的程序(wxWidgets,code :: blocks)中,我注意到一些我不太了解的行为。如果我像这样写我的标题:
#ifndef RECORDTHREAD_H
#define RECORDTHREAD_H
#include <wx/thread.h>
#include <wx/dialog.h>
#include <wx/string.h>
#include "Serial.h"
class RecordTrackDialog;
class RecordThread : public wxThread
{
public:
RecordThread(RecordTrackDialog* parent);
virtual ~RecordThread();
protected:
private:
virtual ExitCode Entry();
Serial m_serial;
};
#endif // RECORDTHREAD_H
(使用#include "Serial.h"
作为最后一个包含语句)一切正常,但是当我更改这样的include语句时:
#ifndef RECORDTHREAD_H
#define RECORDTHREAD_H
#include "Serial.h"
#include <wx/thread.h>
#include <wx/dialog.h>
#include <wx/string.h>
我得到这样的错误:
||=== Build: Debug in WindowsDgpsGUI (compiler: GNU GCC Compiler) ===|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h||In function 'HWND__* CreateDialog(HINSTANCE, LPCTSTR, HWND, DLGPROC)':|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h|38|error: cannot convert 'LPCTSTR {aka const char*}' to 'LPCWSTR {aka const wchar_t*}' for argument '2' to 'HWND__* CreateDialogParamW(HINSTANCE, LPCWSTR, HWND, DLGPROC, LPARAM)'|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h||In function 'HFONT__* CreateFont(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCTSTR)':|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h|69|error: cannot convert 'LPCTSTR {aka const char*}' to 'LPCWSTR {aka const wchar_t*}' for argument '14' to 'HFONT__* CreateFontW(int, int, int, int, int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPCWSTR)'|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h||In function 'HWND__* CreateWindow(LPCTSTR, LPCTSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID)':|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h|94|error: cannot convert 'LPCTSTR {aka const char*}' to 'LPCWSTR {aka const wchar_t*}' for argument '2' to 'HWND__* CreateWindowExW(DWORD, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID)'|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h||In function 'HMENU__* LoadMenu(HINSTANCE, LPCTSTR)':|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h|111|error: cannot convert 'LPCTSTR {aka const char*}' to 'LPCWSTR {aka const wchar_t*}' for argument '2' to 'HMENU__* LoadMenuW(HINSTANCE, LPCWSTR)'|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h||In function 'HWND__* FindText(LPFINDREPLACE)':|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h|126|error: cannot convert 'LPFINDREPLACE {aka FINDREPLACEA*}' to 'LPFINDREPLACEW {aka FINDREPLACEW*}' for argument '1' to 'HWND__* FindTextW(LPFINDREPLACEW)'|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h||In function 'HICON__* LoadIcon(HINSTANCE, LPCTSTR)':|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h|311|error: cannot convert 'LPCTSTR {aka const char*}' to 'LPCWSTR {aka const wchar_t*}' for argument '2' to 'HICON__* LoadIconW(HINSTANCE, LPCWSTR)'|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h||In function 'HBITMAP__* LoadBitmap(HINSTANCE, LPCTSTR)':|
C:\wxWidgets-3.0.2\include\wx\msw\winundef.h|324|error: cannot convert 'LPCTSTR {aka const char*}' to 'LPCWSTR {aka const wchar_t*}' for argument '2' to 'HBITMAP__* LoadBitmapW(HINSTANCE, LPCWSTR)'|
||=== Build failed: 7 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|
我不太明白这种行为,因为标题是一个线程,错误来自使用该线程的对话框。任何人都可以解释为什么C ++(或wxWidgets)表现得像这样吗?
编辑:
Serial.h的包含
#ifndef SERIAL_H
#define SERIAL_H
#include <windows.h>
//#include <wx/msw/winundef.h>
#include <stdio.h> // necessary for sprintf
#include <string>
这似乎符合Marco的评论,但我不能包含该部分......
答案 0 :(得分:1)
正如评论所指出的那样,可能是因为Serial.h
依赖于3 wx\xxxx
个文件中的定义而包含主文件(RecordThread.h
?)。
将它们添加到这样的Serial.h
,你将获得与以前相同的效果。
#ifndef SERIAL_H
#define SERIAL_H
#include <wx/thread.h>
#include <wx/dialog.h>
#include <wx/string.h>
#include <windows.h>
//#include <wx/msw/winundef.h>
#include <stdio.h> // necessary for sprintf
#include <string>
如果您要正确地执行此操作,您应该在Serial.h
中确定您实际需要哪一个(或多个),但添加所有这些应该清除错误。
编译预处理器句柄#include
时,就好像指定的文件被复制到#include
位置的主文件中一样。这是一个递归过程,文件可以#include
文件#include
文件等。
似乎有很多关于#include
的神秘主义和新手中的预处理器。它实际上只是一个文本处理工具。
在现代C的许多地方,你必须在使用之前声明(引入/定义)符号/标识符。如果在头文件中声明了该符号/标识符,则在使用之前应该#include
该文件。
答案 1 :(得分:1)
问题在于<windows.h>
定义了不同的符号,具体取决于是否定义了UNICODE
标准(在Windows下,即在Windows下)。如果您首先包含wxWidgets标头(默认情况下为Unicode构建),那么在包含UNICODE
并且一切正常之前,它们会为您定义<windows.h>
。
如果您首先包含<windows.h>
,则此时未定义UNICODE
,但是当您稍后包含wxWidgets标头时,它们会使用wxUSE_UNICODE=1
(这也是默认值)导致您正在观察的编译问题。
确保您永远不会遇到此类问题的最简单方法是在项目设置或makefile中全局定义UNICODE
。
答案 2 :(得分:0)
只是一些常见的做法需要跟进,这可能无法回答您的问题,但指出了正确的方向:
#include
使用相同的头文件,这意味着会让人感到困惑,但请使用以下图表理解它:<强>有效:强>
-#include "some.h"
-#include "some1.h"
<强>有效:强>
-#include "some.h"
--#include "some1.h"
无效:
-#include "some.h"
-#include "some1.h"
--#include "some.h"
除非你知道自己在做什么,否则不要嵌套......
问题的一个可能解决方案是在wx\thread.h
中加入wx\dialog.h
,wx\string.h
,Serial.h
,试一试,然后告诉我
为什么要按顺序调用#include
?
因为只有了解这样的事情才有意义,阿里需要清理他的车,阿里不知道如何修理他的车,所以阿里会叫机修修理它,所以我们可以说那个(阿里依靠机械师):
- #include "mechanic.h"
- #include "Ali.h"