c++ - 结合 C++ 和 C

标签 c++ c directx directx-11

我正在尝试做一个 DirectX 教程,但我想用 C 而不是 C++ 编写应用程序。所以我用 C 编写了代码,但是当我尝试编译它时,我在“setupD3D”函数上遇到了很多错误。所以我只是将文件重命名为 .cpp。但是新代码也没有编译。我认为结合 C 和 C++ 是问题所在,或者有很多交叉引用。谁能告诉我这段代码中的问题是什么?

direct3d.h:

#include "main.h"

#ifndef DIRECT3D

#define DIRECT3D

int m_videoCardMemory;
char m_videoCardDescription[128];
ID3D11DeviceContext* m_deviceContext = 0;
D3DXMATRIX m_projectionMatrix;
D3DXMATRIX m_worldMatrix;
D3DXMATRIX m_orthoMatrix;

int setupD3D(BYTE vsync, HWND hwnd, float screenDepth, float screenNear);
void terminateD3D();
void beginScene(float red, float green, float blue, float alpha);
void endScene();

#endif

direct3d.cpp

#include "direct3d.h"
// code

主要.h:

#ifndef MAIN_FUNC

#define MAIN_FUNC

#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")

#include <Windows.h>
#include <dxgi.h>
#include <d3dcommon.h>
#include <d3d11.h>
#include <d3dx10math.h>
#include "direct3d.h"

int breedte, hoogte;
LRESULT CALLBACK Actie(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void main_loop(MSG* msg);
void keyevent();

#endif

主.c

#include "main.h"
// code

winstart.c

#include "main.h"
// code

错误:

Error   86  error LNK2005: _m_deviceContext already defined in main.obj
Error   87  error LNK2019: unresolved external symbol _setupD3D referenced in function _Actie@16
Error   88  error LNK2019: unresolved external symbol _terminateD3D referenced in function _Actie@16
Error   89  error LNK2019: unresolved external symbol _beginScene referenced in function _render
Error   90  error LNK2019: unresolved external symbol _endScene referenced in function _render
Error   91  error LNK1120: 4 unresolved externals   

我还有 84 条关于宏重新定义的警告。

最佳答案

如果您在 .cpp 文件中声明函数,编译器会将其编译为 C++ 代码(无论它是否是纯 C 代码)。不幸的是,C++ 有一种叫做 Name mangling 的机制。这允许例如函数重载,而 C 不允许。如果您现在想从 .c 文件(编译器将其识别为纯 C)调用这样的函数,则编译器正在为符号的另一个命名(在您的情况下为函数)创建引用,而不是它们存在并且链接器不存在能够再匹配它们了。

要解决这个问题,您可以在每个您希望 C 调用的函数前放置一个 extern "C"。因为 C 无法识别 extern "C" 你必须使这种语言依赖。

解决这个问题的一种常见方法是在头文件中引入以下结构:

... your include guard of choice

#ifdef __cplusplus
    extern "C" {
#endif

//-- your declarations

#ifdef __cplusplus
    }
#endif

这指示 C++ 编译器创建符合 C 的名称。由于 C 编译器不提供预处理器符号“__cplusplus”,因此它会忽略 extern 语句。 (这没关系,因为 C 编译器总是只创建符合 C 的符号名称)

除了更改头文件(有时您不允许这样做)之外,包含 extern "C" 包含的整个头文件也是合法的:

extern "C" {
    #include <My_C_API.h>
}

关于c++ - 结合 C++ 和 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14606349/

相关文章:

使用类指针重载的 C++ 命名空间函数模板特化替代方案?

c - 使用 freeglut 的 OpenGL 抗锯齿

c - waitpid - WIFEXITED 返回 0 尽管 child 正常退出

用指针调用函数不会改变该指针的值?

c# - 是否可以在 Windows 上使用 .NET 完全接管多个屏幕中的一个屏幕?

c++ - 有没有一种标准的方法来捕获在 linux 和 windows 的 c++ 应用程序中工作的键盘输入?

c++ - 重载函数的调用不明确

c++ - 无法创建 d3d 设备

c++ - 在 MFC 中使用 Direct2D 将 svg 文件转换为位图

c++ - 在 C++ 标准中,下面的代码片段中不允许使用 `a = b + {1, 2}`?