从不同的VS2010项目中的C ++代码调用C函数时出现链接器错误

时间:2015-06-01 19:38:53

标签: c++ c visual-studio-2010 extern lnk2001

我试图包含我在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)
{

包含此项的VS项目正在创建一个dll。该文件正在编译为C,项目中的其他文件正在编译为C ++。

我添加了一个标题以包含在我的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

在解决方案的另一个项目中,我包含我的标题并尝试调用g_fmt函数。

#include "header.h"
...
g_fmt(my_array, 2.0);

这个项目链接到另一个项目,我能够在第一个库中调用C ++函数而没有任何问题。但是,添加上面的行会给我一个lnk2001错误。

error LNK2001: unresolved external symbol g_fmt

我发现了一些关于混合使用C和C ++的其他问题,我似乎已经在正确的位置使用extern关键字做了所有必要的事情,但是我仍然无法链接。在VS2010中我需要做些什么吗?

1 个答案:

答案 0 :(得分:2)

C C ++ 中,考虑到模块可能包含多个对象,每个对象都应该清楚地分隔。此外,每个对象( .c .cpp 文件)都应该有自己的头文件。因此,您应该有一个头文件和一个用于 C 函数的c(xx)文件(在您的示例中为 3 )。此外,作为一般准则,在命名文件和宏时尝试保持一致: header.h 文件使用G_FMT_H宏作为包含保护。因此,请尝试将 .h .c 文件重新组织为:

functions.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

和相应的实现( 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
}

头文件中需要注意的两件事情(除了重新组织和重命名):

  • 每个功能的extern存储说明符已消失
  • 导出逻辑:您的项目现在将定义FUNCTIONS_EXPORT(来自 functions.c ,或所需成为 VStudio 项目设置 - 无论如何,在之前的某个地方 #include "functions.h"
    • 编译此项目( functions.c )时,将导出函数(由于宏定义)
    • 当头文件包含在另一个项目中时(不定义FUNCTIONS_EXPORTS),这些函数将被标记为已导入,链接器将在导入的 lib中搜索它们(s) - 其中一个应该是由该项目生成的
    • 为了更加严谨,您可以通过自动的宏替换FUNCTIONS_EXPORTS(并从 functions.c 中删除其定义) {em> IDE 的#define${YOUR_PROJECT_NAME}_EXPORTS(例如,如果您的 Dll 项目被称为 ExportFunctionsProject.vc(x)proj ,然后宏名称将为EXPORTFUNCTIONSPROJECT_EXPORTS
    • 您可以在 VStudio(2010)IDE 中检查宏名称:项目属性 - > C / C ++ - >预处理器 - >预处理器定义。有关详细信息,请查看[MSDN]: /D (Preprocessor Definitions)

类似(或相关)问题:

EDIT0 :为静态版本添加了"支持"
EDIT1 :跨平台+一些更正。