问题标签 [opaque-pointers]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
614 浏览

c++ - C ++从不透明指针通信私有数据

我最近了解了 C++ 中的不透明指针。我已经开始使用它们来隐藏特定于平台的私有成员。例如引用<windows.h>等中的定义。

现在,我有几个相互构建并需要相互通信的系统。例如,Direct3D 需要一个窗口句柄 (HWND)。我不想将平台定义暴露给我的核心系统,但是我的子系统需要传达这些数据。

我公开了不透明的数据并允许通过 void 指针进行访问。这允许访问所有私人数据。

示例用法(main.cpp):

窗口定义(System/Window.h):

如何检索有用数据(Direct3D9.cpp):

但是,此代码有效!:

有没有办法在子系统之间交流平台特定信息而不将其暴露给我的独立代码 - 并保持私有数据的私密性?


编辑当前的 WindowData 实现

HWND 由 DirectX 在表示参数 ( D3DPRESENT_PARAMETERS::hDeviceWindow)中使用

0 投票
0 回答
432 浏览

c - 使用 C 编程语言的不透明指针与 id 数字的优缺点是什么?

我目前使用不透明指针作为我的标准封装技术,但是查看 OpenGL API 让我认为使用 id 编号可能是更好的选择。我想从经验丰富的 C 程序员那里得到一些建议(我只积极使用该语言大约 2 年)。

以下是我想要确认或纠正的最初想法。

身份证号码的可能优点:

  • 如果使用 id 编号,则在实现中使用对象/内存池相当简单

  • id 号不必映射到系统内存(在 GL 情况下可以参考图形内存)

身份证号码的可能缺点:

  • 使实现稍微复杂一些

考虑到使用共享库的情况,还有一个类似的问题: 我应该为我的不透明对象使用整数 ID 还是指针? 我的问题不是关于共享库,而是关于从用户代码中隐藏实现细节的一般情况。

我想您可以 typedef 一个 MyObjectHandle 以使库能够在 id 号和不透明指针之间切换。

问题是: 使用 C 编程语言的不透明指针与 id 数字的优缺点是什么?

0 投票
1 回答
632 浏览

ios - CGColor内部

我希望通过这项研究了解 CoreFoundation CGColor 对象的内部结构。我可以从免费的石英项目中找到一个 CGColor 结构的示例定义,它似乎与 IOS 声明相匹配(依赖于我的研究)。

(colorID 字段被免费石英命名为 nextID,但我认为它旨在作为 IOS 颜色的唯一标识符,因此它不是一种下一个标识符。)

保持全局线程安全的唯一值,对于创建并分配给 colorID 成员的每个 CGColor 对象,该值递增 1。只有未记录的 CGColorGetIdentifier() 函数返回此值。(我猜想单调增加 id 值,它可以提高性能,同时在设备之间转换为校准颜色查找,反之亦然。)

我检查了 CoreGraphics 及其资源库。我发现只有 ripc_GetColor (libRIP.A.dylib) 函数调用 CGColorGetIdentifier() 函数。

CGColorGetIdentifier 的调用堆栈;(希望有助于推断 colorID)

对于当前颜色图形上下文操作,ripc_GetColor() 计算当前笔触/填充颜色的一些转换,并将这些转换与该颜色的引用和 colorID 一起缓存。

因此,对于下一个图形上下文操作,ripc_GetColor() 比较先前缓存的和当前的参考和 colorID 值,以跳过已经为上一个图形上下文操作缓存的颜色转换。

我们知道在创建另一个对象时可以使用已释放对象的引用(内存地址)。所以仅仅检查引用是不够的,相同的颜色对象是有效的,但我们需要比较内容或某种哈希值。因此,我们可以为此目的使用唯一标识符值。

但是,标识符可以用于单个对象及其引用,因此仅比较 id 就足够了。但是,refs 和 ids 都被使用了。我不认为工程师忽略了这样一个简单而关键的事情。

所以,我试图找出比较 ids 和 refs 的必要性,而只比较 ids 就足够了。

它是从以前的方法遗留下来的,所以不能完全放弃吗?

0 投票
2 回答
507 浏览

c++ - C ++隐藏继承的类?

我试图从链接它的可执行文件中隐藏在我编写的库的主类头中包含第三方文件。我的意思是:

我有一个我编写的库,它定义了 A 类。A 类继承自 B 类(在第三方库中定义)。例子:

B 类的头文件对环境进行了一些更改,这些更改对我的库来说是理想的,但对链接我的库的任何可执行文件都是有害的。有人向我指出不透明指针作为一种潜在的解决方案,尽管我不知道如何使用它们来隐藏“B”。

有谁知道隐藏包含 Bh 的方法?对于解决方案,C++11 是可以的,但链接到其他依赖项(如 boost)不是一种选择。

0 投票
0 回答
139 浏览

c - 有没有办法让 clang 知道自定义不透明类型引用计数?

我有一些不透明的类型,并实现了模仿 Core Foundation 的引用计数语义。除了 clang 警告我半有效的潜在泄漏之外,这已经足够好用了。

我正在寻找类似attribute_cf_consumed或简单的方法来制作我自己的版本。

作为参考,这就是我目前使警告静音的方式。它有效,但在我看来,它与只留下警告一样糟糕。(我 ifdef围绕's call to的if语句)MytypeReleasefree

0 投票
1 回答
399 浏览

c++ - 使用 pimpl 移动类将无法编译

在下面的示例中,如何正确调用 ~CImpl 但是当需要移动类时,编译器说它的类型不完整?

如果将 Impl 的声明移到它工作的标头中,我的问题是为什么析构函数被调用得很好,所以看起来类型不完整,但是移动时出现了问题。

文件:C.hpp

文件 C.cpp

文件:main.cpp

编译器输出:

0 投票
2 回答
271 浏览

c++ - MSVC 中的不透明指针生成编译器错误

main.c

stackg.h

上面的程序用 GCC 编译器编译成功,但是在 MSVC2008 中它给出了以下错误:

我应该告诉 MSVC 什么让它编译程序而不更改代码中的任何内容?

编辑

错误发生在stackg.h::的第 8 行typedef struct stack_gt* stack_gt;

编辑 2

如果没有别的,我会去typedef struct _stack_gt* stack_gt;

0 投票
1 回答
110 浏览

c++ - 是否应该使用未命名的结构或未定义的标记来实现不透明指针?

我目前正在设计一个 API,它允许用户传递一个不透明的指针,稍后当调用他必须实现的接口的方法时,他将被传回。

这基本上归结为以下几点:

API端:

用户端:

在那种情况下定义不透明指针的最佳方法是什么?

基本上我想到了 typedef struct _CustomContext* CustomContext; 哪个定义了一个指向未定义(前向声明)结构的指针。

但我也想知道 typedef struct {} * CustomContext; 哪个定义指向未命名结构的指针是否是一个不错的选择?我看到的主要问题是,如果包含在不同的翻译单元中,它可能会定义不同的结构。对吗?

void*当然,由于类型安全问题,我不想使用 a 。

0 投票
0 回答
130 浏览

templates - 模板化不透明前向声明

我正在尝试创建一个同步的双端队列,该队列将在不同的操作系统上具有不同的实现(例如,Android、Windows、Linux 等上的 std::mutex 和条件变量 - sync_deque_stl.cpp 中的实现;iOS 上的大型中央调度/ MacOS - sync_deque_gcd.cpp 中的实现)。我也在使用 gyp 来生成我的项目。

  1. 我有一个带有以下定义的 sync_deque.hpp 文件:

    /li>
  2. 然后,我使用 gyp 创建:

    • MacOS/iOS 上的 Xcode 项目,包含 sync_deque_gcd.cpp,但不包含 sync_deque_stl.cpp
    • Windows 上的 Visual Studio 项目,包含 sync_deque_stl.cpp,但不包含 sync_deque_gcd.cpp
    • (基本上,每个操作系统都有自己的sync_deque实现.cpp,但头文件在操作系统之间是通用的)
  3. 在 .cpp 文件中,我使用 c++ 类型别名(示例取自 sync_deque_stl.cpp):

    /li>

这是有效的 C++11 语法,但它与 sync_deque.hpp 中的前向声明冲突:

sync_deque_stl.cpp:29:1: 错误:使用 opaque_sync_deque = sync_deque_stl 将“opaque_sync_deque”重新定义为不同类型的符号;

是否仍然可以保留此设置(所有操作系统共享的 .hpp 中的不透明模板类型和函数签名 + 不同操作系统的单独 .cpp 文件中的实现)并且仍然可以编译?我相信我可以在每个目录中有单独的 /gcd 和 /stl 以及单独的 sync_deque 头文件,然后使用 gyp 选择正确的头文件,但是只有一个 sync_deque.hpp 会更容易。任何帮助表示赞赏。

0 投票
1 回答
699 浏览

c - 是否允许从 TYPE*​​ 转换为 unsigned char*?

C99 - 特别是第 6.2.6.1 节第 4 段 - 声明允许将对象表示复制到 unsigned char 数组中:

我的问题:我们不能通过简单的转换来避免额外的内存分配和复制操作吗?例如:

当然,需要跟踪大小,但这首先是合法的,还是属于实现定义或未定义行为的领域?

我问是因为我正在实现一个类似于 的算法qsort,并且我希望它适用于任何类型的数组,就像它qsort一样。