在 C 源文件中包含带有命名空间的 C++ 头文件会导致编译错误

2023-11-23

我不是专业的 C++ 程序员,而且我最近在 C++ 中做了一些技巧,这导致了我出现以下问题。

我的任务目标:复制特定的非系统线程(实际上是协作线程)安全模块以创建系统线程安全版本以支持系统中的不同需求。但我们没有创建 sys_XXX 函数来保持兼容性,而是决定在 C++ 头文件中创建一个命名空间来保护系统线程版本。我实际上可以将其包含在 CPP 文件中并愉快地工作,但我刚刚意识到我的 funcInit 调用在到达 CPP 文件控件之前不会被调用。不幸的是,协作线程版本的 init 位于 C 文件中。现在我需要从同一个地方初始化我的系统线程安全版本,但我已被编译错误阻止,据我所知很难解决。

编译错误日志:-

In file included from sysinit.c:87:
sys_unicode.h:39: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'SystemThreadUtils' <== corresponds to line [namespace SystemThreadUtils {]
sysinit.c:88:
sysinit.c:512: error: expected identifier or '(' before string constant <== corresponds to line [extern "C" bool SystemThreadUtils::funcInit(void);]
sysinit.c:513: error: expected identifier or '(' before string constant <== corresponds to line [extern "C" bool SystemThreadUtils::funcTerm(void);]
sysinit.c: In function 'SysInit':
sysinit.c:817: error: 'SystemThreadUtils' undeclared (first use in this function) <= corresponds to line [SystemThreadUtils::funcInit();]
sysinit.c:817: error: (Each undeclared identifier is reported only once
sysinit.c:817: error: for each function it appears in.)
sysinit.c:817: error: expected ')' before ':' token
sysinit.c: In function 'SysTerm':
sysinit.c:2737: error: expected expression before ':' token <== corresponds to line [SystemThreadUtils::funcTerm();]
sysinit.c:2737: warning: label 'SystemThreadUtils' defined but not used

源代码和标题片段仅供参考:-

C 头文件(unicode.h):

// all functions called from the C source file
funcInit();
funcA();
funcB();
funcTerm();

C 头文件(unicode.c):

// all functions called from the C source file
funcInit() {
}
funcA() {
}
funcB() {
}
funcTerm() {
}

C++ 头文件(sys_unicode.h):

#include "unicode.h"
namespace SystemThreadUtils {

    // below functions called from the C source file
    extern "C" funcInit();
    extern "C" funcTerm();

    // below functions called from the CPP source file
    funcA();
    funcB();
}

C++ 源定义 (sys_unicode.cpp):

#include "sys_unicode.h"

namespace SystemThreadUtils {

    // below functions are called from C source
    funcInit() {
    }
    funcTerm() {
    }

    // below methods are called from CPP source
    funcA() {
    }
    funcB() {
    }
}

CPP 源#1 (utils.cpp):

#include "sys_unicode.h"

using namespace SystemThreadUtils;

utils::utils_init()
{
   funcA();
   funcB();
}

C 源代码 #2 (sysinit.c):

#include "sys_unicode.h"

extern "C" bool SystemThreadUtils::funcInit(void);
extern "C" bool SystemThreadUtils::funcTerm(void);

SysInit ()
{
   funcInit(); // non system thread safe version
   SystemThreadUtils::funcInit();  // system thread safe version
}
SysTerm ()
{
   funcTerm(); // non system thread safe version
   SystemThreadUtils::funcTerm();  // system thread safe version
}

你不能在 C 中使用命名空间,extern "C"在 C 中也是不允许的。那么解决方案是什么:您的 C++ 模块在命名空间中定义了一组函数SystemThreadUtils需要在 C 代码中调用。由于您无法直接执行此操作,因此您必须围绕它们编写一个符合 C 规范的包装器:

//C/C++ - header "sys_unicode_for_c.h"

#ifdef __cplusplus
extern "C" {
#endif

  void STU_funcInit();
  void STU_funcTerm();

#ifdef __cplusplus
} //end extern "C"
#endif

//C++-source: sys_unicode_for_c.hpp
#include "sys_unicode.h"

extern "C" {
  void STU_funcInit() {
    SystemThreadUtils::funcInit();
  }
  void STU_funcTerm() {
    SystemThreadUtils::funcTerm();
  }
}

含义:您需要一个有效的 C 代码标头,并为您需要从 C 调用的每个 C++ 函数声明一个委托函数。源代码位于 C++ 中,并且只执行调用。

See 从 C 文件调用 C++ 函数以及。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C 源文件中包含带有命名空间的 C++ 头文件会导致编译错误 的相关文章

随机推荐

  • Apache Spark 案例在不同列上具有多个 when 子句

    鉴于以下结构 val df Seq Color Shape Range Size map Tuple1 apply toDF color val df1 df withColumn Success when color lt gt whit
  • elasticsearch禁用词频评分

    我想更改 Elasticsearch 中的评分系统 以摆脱对某个术语多次出现的计数 例如 我想要 德克萨斯州 德克萨斯州 德克萨斯州 and texas 得出相同的分数 我发现这个映射 elasticsearch 说会禁用术语频率计数 但我
  • Django Rest框架序列化器排除深度为2的外键

    我制作了一个 api 它以 json 数据的形式返回一个对象 我正在使用 django rest framework 及其序列化器 使用资源 ModelResource 我排除了一些字段 例如名为 所有者 的属性 其中一个字段本身就是外键
  • 关于 Powershell 中的范围

    我正在学习 Powershell 中的范围并有一些问题 关于 本地范围 据我所知 本地范围始终是当前范围 因此 默认情况下 当我们创建一个项目 没有范围修饰符 时 例如一个变量 在某个范围内 让它是脚本或全局 相应的范围将是脚本 全局 所以
  • 将 NSNumberFormatter 的负数格式从 (xxx.xx) 更改为 -xxx.xx

    我想将我的 NSNumberformatter 从显示带括号的负数更改为将减号放在前面 或任何本地化标准 我假设我可以使用 setNegativeFormat 来做到这一点 但读了苹果如此详尽的文档 我还是摸不着头脑 设置负数格式 设置接收
  • 检测特定 div 及其所有子级之外的点击

    我一直在阅读以下内容 https css tricks com dangers stopping event propagation 我想以适当且安全的方式实施这一点 我想当我点击 div 之外的类时container那console lo
  • Haskell 中如何使用 $ 运算符柯里化函数应用?

    我正在学习 haskell 并且有点困惑函数应用运算符 curry 的用法 根据 GHC 的类型是 Main gt t a gt b gt a gt b 但我可以输入以下代码 Main gt map 2 2 2 2 4 0 4 0 1 0
  • 如何获取 ListItemClick 的值并将其传递给另一个活动

    我有一个 listView 里面有信息 当我单击一行时 它必须为我提供该所选行下的所有详细信息 在该选择行中我有图像 图像名称 价格等 因此 当我单击 listView 中的图像时 它必须填充所有信息 包括下一个活动中的图像 我尝试在我的
  • 如何在 HTML 表单中不传递空输入字段

    我有一个表单 其中包含我们公司每种产品的大约一百个输入 文本字段 该表格将在当天结束时填写 并注明所售出的每种产品的数量 如何让表单只传递相对较小的非空字段子集 我不是在寻找表单验证 用户可以在任何输入字段中输入或不输入值 但是 我只希望输
  • 查找行中特定值的最后一次出现

    我有一张桌子 记录着梦幻足球联赛的比分 得分最低的一周不计入总分 我可以使用以下方法找到最低分 min function min B2 R2 我可以使用以下命令找到第一个实例 match function MATCH S2 B2 R2 0
  • 在 Linux 中使用 Core Dump 检查点/重新启动

    可以使用进程的核心转储来实现检查点 重启吗 核心文件包含进程的完整内存转储 因此理论上应该可以 将进程恢复到转储核心时的相同状态 是的 这是可能的 GNU Emacs 这样做是为了优化其启动时间 它加载一堆 Lisp 文件来生成图像 然后转
  • Typescript 中的 Angular:如何将通用类型传递给函数

    使用 Typescript 编写 Angular 5 单元测试 我有一个函数可以查询 DOM 并返回一个实例MyComponent如果找到类 function getMyComponent hostFixture ComponentFixt
  • 如何设置无限循环并打破它。 (Java 线程)

    我已经设置了一个线程 我想使用循环来运行它 所以这个线程应该在循环中运行并在某个时间中断并再次运行循环 请我不知道如何做到这一点 有人可以指导我吗 Java 有一个内置的机制 可以让线程做某事 然后等待一段时间再做一次 称为Timer 您可
  • 使用java库将.class文件反编译为.java源代码

    我正在开发一个需要将 class文件反编译为源代码的java项目 我发现了很多方法 例如JAD反编译器和 javap p 方法 但我认为这些方法无法完成以编程方式 请告知是否可以 有什么方法可以以编程方式完成此操作 如果您向我展示任何库 我
  • 在 angularjs 和express.js 之间进行下载

    我可以获取我请求的文件的原始数据 但无法让浏览器向用户提供文件 我需要使用 iframe 吗 Client code download file function path callback http post download clien
  • 为什么这是未定义的行为?

    为什么以下给定表达式会调用未定义的行为 int i 5 i i i i 1 我的问题受到Als的影响在这里提问 它不是未定义的 在这里回答C 序列点和偏序 我认为这同样适用于 C 这是我在看到该链接之前的回复 逗号运算符引入了一个序列点 并
  • 使用Python下载并解压文件

    我正在尝试下载并打开压缩文件 但在使用 zipfile 的文件类型句柄时似乎遇到问题 运行此命令时 我收到错误 AttributeError addinfourl 实例没有属性 seek import zipfile import urll
  • jQuery UI:仅允许在其自己的父级别内排序,不能在其上方或下方排序

    基本上使用列表结构 我试图使每个 li 在其自己的级别内可排序 但不能在其他级别内排序 所以如果我拖下去Number 1它不会与任何 sub ul 或 li 混合 但只会在下面Number 2 这就是我到目前为止所拥有的 虽然它确实阻止了
  • 无论索引如何,最后一行始终从 DefaultTableModel 中删除

    当我尝试从 java 中的表中删除行时 我遇到一些问题 特别是 我使用DefaultTableModel 当我尝试删除一行时 使用removeRow int row 方法 最后一行被删除 无论什么row是 例如 假设我们有六行 当 的时候r
  • 在 C 源文件中包含带有命名空间的 C++ 头文件会导致编译错误

    我不是专业的 C 程序员 而且我最近在 C 中做了一些技巧 这导致了我出现以下问题 我的任务目标 复制特定的非系统线程 实际上是协作线程 安全模块以创建系统线程安全版本以支持系统中的不同需求 但我们没有创建 sys XXX 函数来保持兼容性