且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-02-12 17:05:25

在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).