Links error when C-code from different VS2010 projects

I am trying to include some C code I found in the C project. The function is defined in the C file as follows.

< pre>#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 included in it is creating a dll. The file is being compiled to C, the other in the project The file is being compiled to C.

I added a header to include in my C file

#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 of the solution, I included my title and tried to call the g_fmt function.

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

This project is linked to another project, I can call C functions in the first library without There will be any problems. However, adding the above line will give me a lnk2001 error.

error LNK2001: unresolved external symbol g_fmt

I found some other questions about mixing C and C, and I seem to have done everything necessary using the extern keyword in the right place, But I still can’t link. Do I need to do something in VS2010?

In C or C, considering that the module may consist of multiple objects, each object Should be clearly separated. Also, each object (.c or .cpp file) should have its own header file. Therefore, you should have a header file and a c(xx) file for C functions (in your example In 3). In addition, as a general rule, try to be consistent when naming files and macros: header.h file uses G_FMT_H macro as include protection. Therefore, try to reorganize .h and .c files into:

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
}

Two things to pay attention to in the header file (except for reorganization and renaming):

>Extern storage instructions for each function The symbols are gone.
>Export logic: Your project will now define FUNCTIONS_EXPORT (from functions.c, or hopefully a VStudio project setting – anyway, somewhere before #include “functions.h”)< /p>

>When this project (functions.c) is compiled, the function will be exported (due to the macro definition)
>When the header file will be included in another project (FUNCTIONS_EXPORTS is not defined), the function will be marked As they have been imported, the linker will search for them in the imported .lib-one of them should be the one produced by this project
> To be more strict, you can replace FUNCTIONS_EXPORTS (and from functions.c Delete its definition in): ${YOUR_PROJECT_NAME} _EXPORTS (for example, if your Dll project is named ExportFunctionsProject.vc(x) proj, then the macro name will be EXPORTFUNCTIONSPROJECT_EXPORTS)
>You can check in VStudio(2010) IDE Macro name: Project Properties -> C/C++ -> Preprocessor -> Preprocessor Definition. For more detailed information, please check [MS.Docs]: /D (Preprocessor Definitions)

Similar (Or related) question:

> [SO]: Excel VBA, Can’t Find DLL Entry Point from a DLL file (@CristiFati’s answ er)
> [SO]: LNK2005 Error in CLR Windows Form (@CristiFati’s answer)

EDIT0: Added “support” for static build. Edit 1: Cross-platform some corrections.

I am trying to include some C code I found in the C project. The function is defined in the C file as follows.

#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 included in it is creating a dll. The file is being compiled to C, the project Other files are being compiled to C.

I added a header to be included in my C file

#ifndef G_FMT_H
#define G_FMT_H
#ifdef __cplusplus
extern "C" {
#endif
extern char *dtoa(double, int, int, int *, int *, char **);< br /> extern char *g_fmt(char *, double);
extern void freedtoa(char*);

#ifdef __cplusplus
}
#endif
#endif //G_FMT_H

In another project of the solution, I included my title and tried to call the g_fmt function.

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

This project is linked to another project, and I can call C functions in the first library without any problems. However, adding the above line will give me a lnk2001 error .

error LNK2001: unresolved external symbol g_fmt

I found some other questions about mixing C and C, and I seem to have used it in the right place The extern keyword does all the necessary things, but I still can’t link. What do I need to do in VS2010?

In C or C, considering that the module may be composed of multiple objects, each object should be clearly separated. In addition, each object (. c or .cpp files) should have their own header files. Therefore, you should have a header file and a c(xx) file for C functions (3 in your example). Also, as a general guideline, in Try to be consistent when naming files and macros: the header.h file uses the G_FMT_H macro as the include protection. Therefore, try to reorganize the .h and .c files into:

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< br />
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, i nt, int, int *, int *, char **) {
//function statements
}

char *g_fmt(char *, double) {
//function statements
}

void freedtoa(char*) {
//function statements
}

Notes in the header file Two things (except for reorganization and renaming):

>The extern storage specifier of each function has disappeared.
>Export logic: Your project will now define FUNCTIONS_EXPORT (from functions.c) , Or hopefully a VStudio project setup-anyway, somewhere before #include “functions.h”)

>When this project (functions.c) is compiled, functions will be exported (due to Macro definition)
>When the header file will be included in another project (FUNCTIONS_EXPORTS is not defined), the functions will be marked as imported and the linker will search for them in the imported .lib-one of them should be generated by this project To be more strict, you can replace FUNCTIONS_EXPORTS with a macro automatically defined by VStudio IDE (and delete its definition from functions.c): ${YOUR_PROJECT_NAME} _EXPORTS (for example, if your Dll project is named ExportFunctionsProject. vc(x) proj, then the macro name will be EXPORTFUNCTIONSPROJECT_EXPORTS)
>You can check the macro name in the VStudio(2010) IDE: Project Properties -> C/C++ -> Preprocessor -> Preprocessor Definition. Related For more detailed information, please see [MS.Docs]: /D (Preprocessor Definitions)

Similar (or related) questions:

> [SO]: Excel VBA, Can’ t Find DLL Entry Point from a DLL file (@CristiFati’s answer)
> [SO]: LNK2005 Error in CLR Windows Form (@CristiFati’ s answer)

EDIT0: Added “support” for static build. Edit 1: Cross-platform some corrections.

Leave a Comment

Your email address will not be published.