简体   繁体   中英

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

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

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

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

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);

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

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?

The question is for VStudio 2010 , but applies to any version .

In C or C++ , considering that a module may 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(xx) file for the 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.
Try reorganizing your .h and .c files to something like:

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

and the corresponding implementation ( 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:

  • The extern storage specifier for each function is gone
  • Exporting logic: your project will define now FUNCTIONS_EXPORT (from functions.c , or desirable to be a VStudio project 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 automatically defined by VStudio IDE : ${YOUR_PROJECT_NAME}_EXPORTS (eg if your Dll project 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)

Similar (or related) issues:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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