【问题标题】:Error including a .h file to the Win32 api in c++在 C++ 中将 .h 文件包含到 Win32 api 时出错
【发布时间】:2016-07-18 23:28:55
【问题描述】:

我开始学习如何使用 Win32 Api 来构建一个 un c++ 程序,并且我已经完成了一个带有 CheckBox 的表单,当你按下它时,程序(应该)执行另一个用 other 编写的代码。 H 问题是,在另一个 cpp 中编写的这段代码有字符串、浮点数、unsigned int 和 char,当我将它们包含在编写表单并尝试构建程序的主 cpp 中时,它显示了超过 17 个错误(一个由变量)我一直在寻找答案,我在这个论坛上看到一个人告诉我添加这个

#define WIN32_LEAN_AND_MEAN

应该可以...我已经尝试过了,但一直在发生。

这里有代码:

#include <windows.h>
//Here I add the include, #include "newcpp.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

static char *title = TEXT("Check Box");

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    MSG  msg;
    WNDCLASS wc = { 0 };
    wc.lpszClassName = TEXT("Check Box");
    wc.hInstance = hInstance;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc = WndProc;
    wc.hCursor = LoadCursor(0, IDC_ARROW);


    RegisterClass(&wc);
    CreateWindow(wc.lpszClassName, title,
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        150, 150, 230, 150, 0, 0, hInstance, 0);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

    switch (msg)
    {
    case WM_CREATE:
    {
        CreateWindow(TEXT("button"), TEXT("Show Title"),
            WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
            20, 20, 185, 35,
            hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
        CheckDlgButton(hwnd, 1, BST_CHECKED);
        break;
    }

    case WM_COMMAND:
    {
        BOOL checked = IsDlgButtonChecked(hwnd, 1);
        if (checked) {
            CheckDlgButton(hwnd, 1, BST_UNCHECKED);
            SetWindowText(hwnd, TEXT(""));
            //Code Should be here like action();
        }
        else {
            CheckDlgButton(hwnd, 1, BST_CHECKED);
            SetWindowText(hwnd, title);
            //and here like anotheraction();
        }
        break;
    }

    case WM_DESTROY:
    {
        PostQuitMessage(0);
        break;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

这里有一张我的错误的照片:

(对不起语言,我一直在尝试将 VS 翻译成英文,但我不知道如何._。但如果需要,我可以翻译所有错误。)

大多数错误都说“已经定义...”,除了第一个错误,它说“找到一个或多个同时定义的符号”

__已编辑

.cpp 主要包含以下内容:

float CharToInt(char* value) {
    stringstream str;
    str << value;
    float x;
    str >> x;
    return x;
}

在这里我测试了我的代码。我把我的函数放在主 cpp 中,仍然给我这个错误。

代码:

#include <windows.h>
#include <iostream>
#include <string>
#include <psapi.h> //yes, so much libs, but I'll need them
#include <sstream>
#pragma comment(lib, "psapi")
using namespace std;
float CharToInt(char* value) {
    stringstream str;
    str << value;
    float x;
    str >> x;
    return x;
}

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

static char *title = TEXT("Check Box");

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    MSG  msg;
    WNDCLASS wc = { 0 };
    wc.lpszClassName = TEXT("Check Box");
    wc.hInstance = hInstance;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc = WndProc;
    wc.hCursor = LoadCursor(0, IDC_ARROW);


    RegisterClass(&wc);
    CreateWindow(wc.lpszClassName, title,
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        150, 150, 230, 150, 0, 0, hInstance, 0);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

    switch (msg)
    {
    case WM_CREATE:
    {
        CreateWindow(TEXT("button"), TEXT("Show Title"),
            WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
            20, 20, 185, 35,
            hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
        CheckDlgButton(hwnd, 1, BST_CHECKED);
        break;
    }

    case WM_COMMAND:
    {
        BOOL checked = IsDlgButtonChecked(hwnd, 1);
        if (checked) {
            CheckDlgButton(hwnd, 1, BST_UNCHECKED);
            SetWindowText(hwnd, TEXT(""));
            //Code Should be here like action();
        }
        else {
            CheckDlgButton(hwnd, 1, BST_CHECKED);
            SetWindowText(hwnd, title);
            //and here like anotheraction();
        }
        break;
    }

    case WM_DESTROY:
    {
        PostQuitMessage(0);
        break;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

错误: IMG

1-“发现一个或多个同时定义的符号” 2-“已经定义……”

【问题讨论】:

标签: c++ api winapi compiler-errors


【解决方案1】:

问题是你无意中在多个地方定义了相同的东西。

您应该#include 头文件,而不是 .cpp 文件。

您应该将接口(结构定义、函数原型、类型定义等)分解到您的标题中,并且只将函数定义保留在 .cpp 中。

您的标题应始终包含include guard

#ifndef MYHEADER_H
#define MYHEADER_H

struct mystruct {
    int i;
};

#endif 
/* MYHEADER_H */

另见:

================================================ ===

附录:

如果你这样做:

// main1.cpp
#include <windows.h>
#include <iostream>

float CharToInt(char* value) {
    stringstream str;
    str << value;
    float x;
    str >> x;
    return x;
}

然后这样做:

// main.cpp
#include <windows.h>
#include "main1.cpp"  // BAD PRACTICE!!!!

int main (int argc, char *argv[]) {
  ...

那你是在自找麻烦!不要这样做!!!

相反,您应该这样做:

// myheader.h
#ifndef MYHEADER_H
#define MYHEADER_H

#include <windows.h>
#include <iostream>

float CharToInt(char* value);
... // other function prototypes, struct definitions, typedefs, externs as needed

#endif
// MYHEADER_H

不幸的是,即使我上面描述的“坏”代码也不一定会导致重复符号错误......除非你碰巧在 main1.cpp 和 main.cpp 中实现 CharToInt()。

但这只是不好的做法。

而且我认为实际问题与上面的“坏代码”非常相似。

我真的相信如果你:

a) 将所有函数原型和结构定义分解到标题中

b) 在标题中使用了包含保护

c) 在完全一致 .cpp 中实现您的函数 - 确保 .cpp 中的函数签名与 .h 标头中的函数原型匹配

...那么问题就会“消失”。

我真诚地希望对您有所帮助...

【讨论】:

  • 但是我没有在一个 cpp 和另一个 cpp 中定义变量,我只是在 cpp 中定义了我想要包含的变量以及我在这里展示的代码
  • 如果你在 ."xcpp" 中定义了 "foo" ... 如果你在多个地方 #include'ed x.cpp ... 那么你已经定义了 "foo “ 多次。请告诉我你不是#include cpp 文件!那会很糟糕!
  • 我刚刚注意到我的第一个 cpp 包含到第二个 cpp,然后正如您所说,我应该将第二个 cpp 的所有元素定义为第一个(表单)包括它(即使我没有在第一个定义它们)这就是它发生的原因,对吧?还有一件事,我所有的变量都在函数内部。我只是说
  • 老兄,LNK2005 是因为你(不知何故)多次声明同一个符号。根据您所说的,这听起来像是因为您#include 一个.cpp。如果是这样:不要那样做!将您的定义(包括函数原型)放在 .h 标头 中,并且只包含 .h 文件,从不包含 .cpp 文件。创建标题时,不要忘记添加标题保护。如果之后仍有问题,请更新您的帖子。
  • 问:你能告诉我们更多关于 main.cpp 和 main1.cpp (重复发生的地方)的信息吗?或者更好的是,你能用一个简单的两个 .cpp 示例重现问题吗:How to create a Minimal, Complete, and Verifiable example
猜你喜欢
  • 1970-01-01
  • 2010-12-16
  • 2018-05-14
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 2022-01-07
相关资源
最近更新 更多