从不同 VS2010 项目中的 C++ 代码调用 C 函数时出现链接器错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30581837/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Linker error when calling a C function from C++ code in different VS2010 project
提问by Boumbles
I'm trying to include some C code I found in our C++ project. The function is defined like this in the C file.
我正在尝试包含在我们的 C++ 项目中找到的一些 C 代码。该函数在 C 文件中是这样定义的。
#ifdef __cplusplus
extern "C" {
#endif
extern char *dtoa(double, int, int, int *, int *, char **);
extern char *g_fmt(char *, double);
extern void freedtoa(char*);
#ifdef __cplusplus
}
#endif
char *
g_fmt(register char *b, double x)
{
The VS project I'm including this in is creating a dll. The file is being compiled as C, other files in the project are being compiled as C++.
我在其中包含的 VS 项目正在创建一个 dll。该文件正在编译为 C,项目中的其他文件正在编译为 C++。
I added a header to include in my C++ files
我添加了一个标头以包含在我的 C++ 文件中
#ifndef G_FMT_H
#define G_FMT_H
#ifdef __cplusplus
extern "C" {
#endif
extern char *dtoa(double, int, int, int *, int *, char **);
extern char *g_fmt(char *, double);
extern void freedtoa(char*);
#ifdef __cplusplus
}
#endif
#endif //G_FMT_H
In another project in the solution I include my header and try calling the g_fmt function.
在解决方案的另一个项目中,我包含了我的标题并尝试调用 g_fmt 函数。
#include "header.h"
...
g_fmt(my_array, 2.0);
This project is linking to the other one, I'm able to call C++ functions in the first library without any issues. However, adding the above line gives me a lnk2001 error .
这个项目正在链接到另一个项目,我可以毫无问题地调用第一个库中的 C++ 函数。但是,添加上面的行会给我一个 lnk2001 错误。
error LNK2001: unresolved external symbol g_fmt
I've found a number of other questions about mixing C and C++ and I seem to have done everything necessary with the extern keywords in the right places, however I'm still not able to link. Is there anything specific I need to do in VS2010?
我发现了一些关于混合 C 和 C++ 的其他问题,我似乎已经在正确的位置使用 extern 关键字完成了所有必要的操作,但是我仍然无法链接。在 VS2010 中我需要做什么具体的事情吗?
回答by CristiFati
The question is for VStudio 2010, but applies to any version.
问题是针对VStudio 2010 的,但适用于任何版本。
In Cor C++, considering that a module may consist of multiple objects, every object should be clearly delimited. Also, every object (.cor .cppfile) should have its own header file. So, you should have one header file and one .c(xx)file for the Cfunctions (3in your example).
Also, as a general guideline, try to be consistent when naming files and macros: your header.hfile uses G_FMT_Hmacro as include guard.
Try reorganizing your .hand .cfiles to something like:
在C或C++ 中,考虑到一个模块可能由多个对象组成,每个对象都应该明确界定。此外,每个对象(.c或.cpp文件)都应该有自己的头文件。因此,您应该有一个头文件和一个用于C函数的.c(xx)文件(在您的示例中为3)。此外,作为一般准则,在命名文件和宏时尽量保持一致:您的header.h文件使用G_FMT_H宏作为包含保护。尝试将您的.h和.c文件重新组织为以下内容:
functions.h:
函数.h:
#pragma once
#if defined(_WIN32)
# if defined(FUNCTIONS_STATIC)
# define FUNCTIONS_API
# else
# if defined(FUNCTIONS_EXPORTS)
# define FUNCTIONS_API __declspec(dllexport)
# else
# define FUNCTIONS_API __declspec(dllimport)
# endif
# endif
#else
# define FUNCTIONS_API
#endif
#if defined(__cplusplus)
extern "C" {
#endif
FUNCTIONS_API char *dtoa(double, int, int, int*, int*, char**);
FUNCTIONS_API char *g_fmt(char*, double);
FUNCTIONS_API void freedtoa(char*);
#if defined(__cplusplus)
}
#endif
and the corresponding implementation (functions.c):
以及相应的实现(functions.c):
#define FUNCTIONS_EXPORTS
#include "functions.h"
char *dtoa(double, int, int, int*, int*, char**) {
//function statements
}
char *g_fmt(char*, double) {
//function statements
}
void freedtoa(char*) {
//function statements
}
2 things to notice here (besides reorganizing and renaming) in the header file:
头文件中需要注意的 2 件事(除了重组和重命名):
- The externstorage specifier for each function is gone
- Exporting logic: your project will define now FUNCTIONS_EXPORT(from functions.c, or desirableto be a VStudioproject setting - anyway, somewhere before
#include "functions.h"
)- When this project (functions.c) will be compiled, the functions will be exported (due to the macro definition)
- When the header file will be included in another project (that doesn't define FUNCTIONS_EXPORTS), the functions will be marked as imported, and the linker will search for them in the imported .lib(s) - one of them should be the one generated by this project
- To be more rigorous, you could replace the FUNCTIONS_EXPORTS(and remove its definition from functions.c) by a macro that's automaticallydefined by VStudio IDE: ${YOUR_PROJECT_NAME}_EXPORTS(e.g. if your Dllproject is called ExportFunctionsProject.vc(x)proj, then the macro name will be EXPORTFUNCTIONSPROJECT_EXPORTS)
- You can check the macro name in VStudio (2010) IDE: Project Properties -> C/C++ -> Preprocessor -> Preprocessor definitions. For more details, check [MS.Docs]: /D (Preprocessor Definitions)
- 每个函数的extern存储说明符不见了
- 导出逻辑:您的项目现在将定义FUNCTIONS_EXPORT(来自functions.c,或者希望成为VStudio项目设置 - 无论如何,之前的某个地方
#include "functions.h"
)- 编译此项目 ( functions.c) 时,将导出函数(由于宏定义)
- 当头文件将包含在另一个项目中(未定义FUNCTIONS_EXPORTS)时,这些函数将被标记为已导入,并且链接器将在导入的.lib(s) 中搜索它们- 其中一个应该是本项目生成
- 更严格地说,您可以用VStudio IDE自动定义的宏替换FUNCTIONS_EXPORTS(并从functions.c 中删除其定义):${YOUR_PROJECT_NAME}_EXPORTS(例如,如果您的Dll项目称为ExportFunctionsProject.vc(x)proj,那么宏名称将为EXPORTFUNCTIONSPROJECT_EXPORTS)
- 您可以在VStudio (2010) IDE 中检查宏名称:Project Properties -> C/C++ -> Preprocessor -> Preprocessor definition。有关更多详细信息,请查看[MS.Docs]:/D(预处理器定义)
Similar (or related) issues:
类似(或相关)问题: