問題描述
我正在嘗試包含在我們的 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)
{
我包含它的 VS 項目正在創建一個 dll.該文件正在編譯為 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?
推薦答案
問題針對 VStudio 2010,但適用于任何版本.
The question is for VStudio 2010, but applies to any version.
在 C 或 C++ 中,考慮到一個模塊可能由多個對象組成,每個對象都應該明確界定.此外,每個對象(.c 或 .cpp 文件)都應該有自己的頭文件.因此,您應該有一個頭文件和一個 .c(xx) 文件用于 C 函數(在您的示例中為 3).
此外,作為一般準則,在命名文件和宏時盡量保持一致:您的 header.h 文件使用 G_FMT_H 宏作為包含保護.
嘗試將您的 .h 和 .c 文件重新組織為以下內容:
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
和相應的實現(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 件事(除了重組和重命名):
2 things to notice here (besides reorganizing and renaming) in the header file:
- 每個函數的 extern 存儲說明符不見了
- 導出邏輯:您的項目現在將定義FUNCTIONS_EXPORT(來自functions.c,或希望成為VStudioem> 項目設置 - 無論如何,在之前
#include "functions.h"
)- 編譯此項目 (functions.c) 時,將導出函數(由于宏定義)
- 當頭文件將包含在另一個項目中(沒有定義FUNCTIONS_EXPORTS)時,函數將被標記為已導入,鏈接器將在導入的中搜索它們.lib(s) - 其中之一應該是這個項目生成的
- 更嚴格地說,您可以用自動定義的宏替換FUNCTIONS_EXPORTS(并從functions.c中刪除其定義)通過 VStudio IDE:${YOUR_PROJECT_NAME}_EXPORTS(例如,如果您的 Dll 項目被稱為 ExportFunctionsProject.vc(x)projem>,那么宏名稱將是 EXPORTFUNCTIONSPROJECT_EXPORTS)
- 您可以在 VStudio (2010) IDE 中查看宏名稱:項目屬性 -> C/C++ -> 預處理器 -> 預處理器定義.有關更多詳細信息,請查看 [MS.Docs]:/D(預處理器定義)
- 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 (e.g. 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)
類似(或相關)問題:
- [SO]:Excel VBA,無法從 DLL 文件中找到 DLL 入口點(@CristiFati 的回答)
- [SO]:CLR Windows 窗體中的 LNK2005 錯誤(@CristiFati 的答案)
這篇關于從不同 VS2010 項目中的 C++ 代碼調用 C 函數時出現鏈接器錯誤的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!
【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!