在不同的VS2010项目中从C ++代码调用C函数时的链接器错误 [英] Linker error when calling a C function from C++ code in different VS2010 project

查看:194
本文介绍了在不同的VS2010项目中从C ++代码调用C函数时的链接器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想包含我在C ++项目中找到的一些C代码。该函数在C文件中是这样定义的。

I'm trying to include some C code I found in our C++ project. The function is defined like this in the C file.

#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)
{

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

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

我添加了一个标题以包含在我的C ++文件中

I added a header to include in my C++ files

#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函数。

In another project in the solution I include my header and try calling the g_fmt function.

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

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

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 .

error LNK2001: unresolved external symbol g_fmt

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

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 ++模块中包含多个对象明确划分。每个对象(c或cpp文件)也应该有自己的头文件。因此,您应该有一个头文件和一个c文件为您的c函数(在您的示例中为3)。另外作为一般准则尝试在命名文件和宏时保持一致:您的 header.h 文件使用 G_FMT_H 宏包括警卫。所以尝试重新组织你的c .h和.c文件到如下:

in C/C++ module that consist of multiple objects every object should be clearly delimited. Also every object (c or cpp file) should have its own header file. So you should have one header file and one c file for your c functions (3 in your example). Also as a general guideline try to be consistent when naming files and macros: your header.h file uses G_FMT_H macro as include guard. So try reorganizing your c .h and .c files to something like:

//contents of cfunctions.h
#ifndef __CFUNCTIONS_H__
#define __CFUNCTIONS_H__

#ifdef CFUNCTIONS_EXPORT
#define CFUNCTIONS_API __declspec(dllexport)
#else
#define CFUNCTIONS_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif
    CFUNCTIONS_API char *dtoa(double, int, int, int *, int *, char **);
    CFUNCTIONS_API char *g_fmt(char *, double);
    CFUNCTIONS_API void freedtoa(char*);
#ifdef __cplusplus
}
#endif

#endif  //__CFUNCTIONS_H__

和相应的实现:

//contents of cfunctions.c
#define CFUNCTIONS_EXPORT
#include "cfunctions.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:


  • extern 存储说明符 CFUNCTIONS_EXPORT (从 cfunctions.c ) code>)所以当这个工程将被编译的函数将被导出,但是当这个头将被包括从另一个项目,将不会定义 CFUNCTIONS_EXPORT 的函数将被标记为导入,链接器将在导入的 .lib 文件中搜索它们。为了更严谨,你可以用一个宏替换 CFUNCTIONS_EXPORT (并从 cfunctions.c 中删除​​它的定义)由VisualStudio自动定义:$ {YOURPROJECTNAME} _EXPORTS;所以如果你的dll工程被调用 CppProject.vcxproj 那么宏名称将是`CPPPROJECT_EXPORTS(你可以在项目属性 - > C / C ++ - >预处理器 - >预处理程序定义)。

  • the extern storage specifier for each function is gone
  • exporting logic: your project will define now CFUNCTIONS_EXPORT (from cfunctions.c) so when this project will be compiled the functions will be exported, but when this header will be included from another project that won't define CFUNCTIONS_EXPORT the functions will be marked as imported and the linker will search for them in the imported .lib file. To be more riguros, you could replace the CFUNCTIONS_EXPORT (and remove its definition from cfunctions.c) by a macro that's automatically definded by VisualStudio: ${YOURPROJECTNAME}_EXPORTS; so if your dll project is called CppProject.vcxproj then the macro name will be `CPPPROJECT_EXPORTS (you can check the macro name in Project Properties -> C/C++ -> Preprocessor -> Preprocessor definitions).

这篇关于在不同的VS2010项目中从C ++代码调用C函数时的链接器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆