【问题标题】:Unable to call C++ function from a C code无法从 C 代码调用 C++ 函数
【发布时间】:2018-02-10 18:16:58
【问题描述】:

我是混合 C 和 C++ 代码的新手。在阅读了一些 SO 链接和在线阅读之后,了解了 extern 和 __cplusplus 指令的需要。 不知道为什么我会收到错误。我错过了什么吗?

C++ 头文件:cppexh.h

#include <iostream>

#ifdef __cplusplus
extern "C" {
#endif

void Callme(int a);

#ifdef __cplusplus
}
#endif

C++ 源代码

#include "cppexh.h"

void Callme(int a)
{
    std::cout << "Val is " << a << std::endl;
}

C 代码调用 C++ 函数

#include <stdio.h>
#include "cppexh.h"

int main()
{
    CallMe(2);
    retun 1;
}

但我遇到了编译错误:

1>------ Rebuild All started: Project: CProject, Configuration: Debug Win32 ------
1>  Ccode.c
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtgmath.h(214): warning C4602: #pragma pop_macro : 'new' no previous #pragma push_macro for this identifier
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtgmath.h(215): warning C4193: #pragma warning(pop) : no matching '#pragma warning(push)'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtgmath.h(216): warning C4161: #pragma pack(pop...) : more pops than pushes
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(23): error C2061: syntax error : identifier 'abs'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(23): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(23): error C2061: syntax error : identifier 'acos'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(23): error C2061: syntax error : identifier 'asin'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(24): error C2061: syntax error : identifier 'atan'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(24): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(24): error C2061: syntax error : identifier 'atan2'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(24): error C2061: syntax error : identifier 'ceil'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(25): error C2061: syntax error : identifier 'cos'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(25): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(25): error C2061: syntax error : identifier 'cosh'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(25): error C2061: syntax error : identifier 'exp'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(26): error C2061: syntax error : identifier 'fabs'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(26): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(26): error C2061: syntax error : identifier 'floor'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(26): error C2061: syntax error : identifier 'fmod'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(27): error C2061: syntax error : identifier 'frexp'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(27): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(27): error C2061: syntax error : identifier 'ldexp'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(27): error C2061: syntax error : identifier 'log'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(28): error C2061: syntax error : identifier 'log10'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(28): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(28): error C2061: syntax error : identifier 'modf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(28): error C2061: syntax error : identifier 'pow'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(29): error C2061: syntax error : identifier 'sin'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(29): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(29): error C2061: syntax error : identifier 'sinh'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(29): error C2061: syntax error : identifier 'sqrt'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(30): error C2061: syntax error : identifier 'tan'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(30): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(30): error C2061: syntax error : identifier 'tanh'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(32): error C2061: syntax error : identifier 'acosf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(32): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(32): error C2061: syntax error : identifier 'asinf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(33): error C2061: syntax error : identifier 'atanf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(33): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(33): error C2061: syntax error : identifier 'atan2f'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(33): error C2061: syntax error : identifier 'ceilf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(34): error C2061: syntax error : identifier 'cosf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(34): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(34): error C2061: syntax error : identifier 'coshf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(34): error C2061: syntax error : identifier 'expf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(35): error C2061: syntax error : identifier 'fabsf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(35): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(35): error C2061: syntax error : identifier 'floorf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(35): error C2061: syntax error : identifier 'fmodf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(36): error C2061: syntax error : identifier 'frexpf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(36): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(36): error C2061: syntax error : identifier 'ldexpf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(36): error C2061: syntax error : identifier 'logf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(37): error C2061: syntax error : identifier 'log10f'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(37): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(37): error C2061: syntax error : identifier 'modff'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(37): error C2061: syntax error : identifier 'powf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(38): error C2061: syntax error : identifier 'sinf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(38): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(38): error C2061: syntax error : identifier 'sinhf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(38): error C2061: syntax error : identifier 'sqrtf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(39): error C2061: syntax error : identifier 'tanf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(39): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(39): error C2061: syntax error : identifier 'tanhf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(41): error C2061: syntax error : identifier 'acosl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(41): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(41): error C2061: syntax error : identifier 'asinl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(42): error C2061: syntax error : identifier 'atanl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(42): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(42): error C2061: syntax error : identifier 'atan2l'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(42): error C2061: syntax error : identifier 'ceill'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(43): error C2061: syntax error : identifier 'cosl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(43): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(43): error C2061: syntax error : identifier 'coshl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(43): error C2061: syntax error : identifier 'expl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(44): error C2061: syntax error : identifier 'fabsl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(44): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(44): error C2061: syntax error : identifier 'floorl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(44): error C2061: syntax error : identifier 'fmodl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(45): error C2061: syntax error : identifier 'frexpl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(45): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(45): error C2061: syntax error : identifier 'ldexpl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(45): error C2061: syntax error : identifier 'logl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(46): error C2061: syntax error : identifier 'log10l'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(46): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(46): error C2061: syntax error : identifier 'modfl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(46): error C2061: syntax error : identifier 'powl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(47): error C2061: syntax error : identifier 'sinl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(47): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(47): error C2061: syntax error : identifier 'sinhl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(47): error C2061: syntax error : identifier 'sqrtl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(48): error C2061: syntax error : identifier 'tanl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(48): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(48): error C2061: syntax error : identifier 'tanhl'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(50): error C2054: expected '(' to follow 'using'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(50): error C2061: syntax error : identifier 'using'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(52): error C2061: syntax error : identifier 'acosh'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(52): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(52): error C2061: syntax error : identifier 'asinh'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(52): error C2061: syntax error : identifier 'atanh'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(53): error C2061: syntax error : identifier 'cbrt'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(53): error C2059: syntax error : ';'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(53): error C2061: syntax error : identifier 'erf'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(53): error C2061: syntax error : identifier 'erfc'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cmath(53): fatal error C1003: error count exceeds 100; stopping compilation
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

代码第 2 版

编辑了解决编译问题但链接错误仍然存​​在的代码

#ifdef __cplusplus
#include <iostream>
#endif

#ifdef __cplusplus
extern "C" {
#endif

void Callme(int a);

#ifdef __cplusplus
}
#endif

我的 C++ 代码是一个静态库。

链接错误

1>------ Rebuild All started: Project: CProject, Configuration: Debug Win32 ------
1>  Ccode.c
1>c:\users\ngk\documents\ccg\vsprojects\expapp\cproject\ccode.c(6): warning C4013: 'CallMe' undefined; assuming extern returning int
1>Ccode.obj : error LNK2019: unresolved external symbol _CallMe referenced in function _main
1>C:\Users\ngk\Documents\CCG\VSprojects\ExpApp\Debug\CProject.exe : fatal error LNK1120: 1 unresolved externals
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

【问题讨论】:

  • &lt;iostream&gt; 是 C++ 标头。从通用标题中删除它。
  • 您正在包括 &lt;iostream&gt;,一个 C++ 标头,来自 cppex.h,它包含在 C 代码中。所以C编译器在尝试编译C++,头疼。
  • 你不能指望 C 编译器可以编译 C++ 代码,对吧?
  • @codeLover 通常不应在头文件中包含头文件。特别是在这种情况下,它会造成很多麻烦。此外,在这种情况下,您不需要在头文件中包含 。仅保留在头文件、函数声明、typedefs 和有时可能是 struct 定义中,如果您需要来自另一个头文件的类型并且它用于指针参数或结构成员,只需使用前向声明。
  • main 中,您调用CallMe,但您的函数名为Callmem 的情况不同。

标签: c++ c extern linkage extern-c


【解决方案1】:

移动

#include <iostream>

进入 c++ 源文件。

如果此标头中的 C++ 代码包含在 main() 翻译单元中,C 编译器将无法处理它。

还要注意在声明、定义和调用中使用完全相同的函数名称和参数类型。两个编译器都区分大小写。

CallMe(int)Callme(int) 不同。


至于您的编辑:

确保将静态库正确添加到项目中。

【讨论】:

  • 您可以详细说明为什么这可以解决问题。
  • @IharobAlAsimi 更好吗?
  • 我可以解决编译问题,但是在我编辑我的问题版本 2 时将链接错误作为未解决的外部符号。
  • @codeLover extern "C" 声明应该可以防止名称修改。你如何链接你的翻译单元编译器结果。请将此添加到您的问题中。此外,您应该按照我的建议将 include 语句从标题中移出。
  • @user0042:当您说“您如何链接您的翻译单元编译器结果。”时,我没有听懂您的意思。我正在静态链接,因为我的 C++ 代码是静态库,而我的 C 代码是 EXE。
【解决方案2】:

我有一个可爱的不幸,不得不结合一个调用本土 C++ 的主 C 程序。

至于您的第一个问题(正如其他人所说),将#include &lt;iostream&gt; 移动到您的 C++ 文件中。

至于你的链接器问题:

这可能(或可能不会)是类似的事情,让我旋转我的轮子。但要记住这一点,因为它非常愚蠢。

假设您在 DLL 中构建 C++ 代码,并在调用 DLL 库的 exe 中单独编译 C 代码:

在 Visual Studio 的 Unmanaged C 中,DLL 不会从“Release”中清除 文件夹,就像他们在 Managed C++ 中所做的那样。您必须实际移动您的 将新 DLL 放入应用程序的“Release”文件夹中 更改 DLL 的时间。

我学会了如何在 Managed C++ 中更新 DLL,您所要做的就是(在您的应用程序文件夹中)清除旧的 DLL“库子文件夹”并复制到新版本中将更改后的 DLL 放入那个空的“库子文件夹”中。当您“清理并重建”调用这些 DLL 的主应用程序时,Visual Studio Managed C++ 将从“Release”文件夹中删除旧 DLL,并从“库子文件夹”中复制新 DLL进入应用程序“Release”文件夹。它可以很好地使您的 DLL 保持最新。

非托管 C 中,“清理和重建”不会从应用程序的“发布”文件夹中删除您的旧 DLL。而且它不会从您的“库子文件夹”中复制新的 DLL。因此,即使我认为我将我的新 DLL 放在我的程序可以找到它们的文件夹中,它们并没有像在托管 C++ 下那样被复制。

这基本上意味着您对 C++ DLL 所做的任何新更改...如果您只是将它们复制到 C 项目中的“库子文件夹”,则新改进的代码不会被复制到发行版像托管 C++ 这样的文件夹。您还必须将这些新的 DLL 复制到 Release 文件夹中。

这也意味着...如果您编译并链接了初始 DLL,然后添加了 Callme() 函数,如果您没有将该 DLL 物理复制到您的 Release 文件夹,它将永远不会看到您的新代码。它仍然会查看您的旧版本,并会给出您现在看到的错误。

这里有一些工具可以帮助您追踪您的程序真正尝试调用的版本的日期。这些将让您知道您的链接器是否正在抓取您的代码的过时版本:

link /dump /exports CPPSource.dll | grep subCreate

link /dump /exports CSource.exe | grep subCreate

为 .dll 和 .exe 输入正确的文件名

如果您的 C++ 库没有使用 DLL,请忽略我为您提供的解决方案。 (或者您可以考虑将 DLL 用于纯 C++ 代码并在纯 C 应用程序/项目中调用/链接到它。)我发现将 C++ 代码与主 C 代码项目完全分开在 DLL 中是一种保存方法你从许多头痛。 (尤其是当您混合使用非托管代码和托管代码时。)

希望有帮助:)

【讨论】:

    【解决方案3】:

    您的 C++ 函数需要标记为 extern "C" 以避免名称混淆并遵循 C 调用约定。 如果您不这样做,它将无法(轻松)从 C 中调用。

    上述内容也意味着您不能对需要从 C 调用的此类函数使用默认参数值或重载(以及更多)。

    当然,你需要用 C++ 编译器编译 C++ 代码。

    【讨论】:

      【解决方案4】:

      只是一个愚蠢的错字!您正在声明和定义 Callme() 并调用 CallMe()

      【讨论】:

      • @user0042 你是说#include &lt;iostream&gt; 的东西吗?我认为这是通过给定的链接器输出解决的问题,这指出了我的错字。
      • 我当然是这个意思。还暗示 OP 是 stupid 不是很好。并写出完整的答案。
      • 并且应该对拼写错误进行投票以结束问题,因为这样答案仅对特定情况有用,并且只要存在拼写错误。
      【解决方案5】:

      您不能使用 C 编译器编译 C++ 代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-26
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-27
        • 2013-07-28
        • 1970-01-01
        相关资源
        最近更新 更多