繁体   English   中英

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

[英]Linker error when calling a C function from C++ code in different VS2010 project

我正在尝试包含在我们的 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 中我需要做什么具体的事情吗?

问题是针对VStudio 2010 的,但适用于任何版本

CC++ 中,考虑到一个模块可能由多个对象组成,每个对象都应该明确界定。 此外,每个对象( .c.cpp文件)都应该有自己的头文件。 因此,您应该有一个头文件和一个用于C函数的.c(xx)文件(在您的示例中为3 )。
此外,作为一般准则,在命名文件和宏时尽量保持一致:您的header.h文件使用G_FMT_H宏作为包含保护。
尝试将您的.h.c文件重新组织为以下内容:

函数.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
}

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

  • 每个函数的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(预处理器定义)

类似(或相关)问题:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM