标签: opaque-pointers

不透明的C结构:它们应该如何声明?

我已经看到以下两种在C API中声明不透明类型的样式.使用一种风格而不是另一种风格有明显的优势吗?

选项1

// foo.h
typedef struct foo * fooRef;
void doStuff(fooRef f);

// foo.c
struct foo {
    int x;
    int y;
};
Run Code Online (Sandbox Code Playgroud)

选项2

// foo.h
typedef struct _foo foo;
void doStuff(foo *f);

// foo.c
struct _foo {
    int x;
    int y;
};
Run Code Online (Sandbox Code Playgroud)

c struct coding-style typedef opaque-pointers

46
推荐指数
2
解决办法
3万
查看次数

静态分配不透明数据类型

在为嵌入式系统编程时,通常不允许使用malloc().大部分时间我都能够处理这个问题,但有一件事让我感到恼火:它使我无法使用所谓的"不透明类型"来启用数据隐藏.通常我会做这样的事情:

// In file module.h
typedef struct handle_t handle_t;

handle_t *create_handle();
void operation_on_handle(handle_t *handle, int an_argument);
void another_operation_on_handle(handle_t *handle, char etcetera);
void close_handle(handle_t *handle);


// In file module.c
struct handle_t {
    int foo;
    void *something;
    int another_implementation_detail;
};

handle_t *create_handle() {
    handle_t *handle = malloc(sizeof(struct handle_t));
    // other initialization
    return handle;
}
Run Code Online (Sandbox Code Playgroud)

你去:create_handle()执行malloc()来创建'实例'.通常用于防止必须使用malloc()的构造是更改create_handle()的原型,如下所示:

void create_handle(handle_t *handle);
Run Code Online (Sandbox Code Playgroud)

然后调用者可以这样创建句柄:

// In file caller.c
void i_am_the_caller() {
    handle_t a_handle;    // Allocate a handle on the stack instead of malloc()
    create_handle(&a_handle);
    // ... a_handle …
Run Code Online (Sandbox Code Playgroud)

c embedded opaque-pointers

39
推荐指数
4
解决办法
6479
查看次数

在"CFBundleRef opaque类型"的上下文中,术语"不透明类型"是什么意思?

有人对"不透明类型"有什么好的解释吗?我在上下文中看到了这个术语CFBundleRef,他们说的是:"CFBundleRef opaque type".这是一种只读的类型吗?

iphone objective-c opaque-pointers

29
推荐指数
2
解决办法
7307
查看次数

c typedef(ed)opaque指针

我已经定义了一个不透明的结构和相关的API,如下所示:

typedef struct foo foo;
foo *create_foo(...);
delete_foo(foo *f);
Run Code Online (Sandbox Code Playgroud)

我无法在我的c文件中定义结构.给出重新定义错误.

typedef struct foo {
   int implementation;
}foo;
Run Code Online (Sandbox Code Playgroud)

我可以在没有typedef的c文件中使用foo,但我想要typedef(即直接使用它作为foo*).有办法吗?

c struct typedef opaque-pointers

15
推荐指数
1
解决办法
5546
查看次数

在C中的堆栈上可分配的不透明类型

在设计C接口时,通常只允许.h用户程序需要知道的公共接口().

因此,例如,如果用户程序不需要知道它们,则结构的内部组件应该保持隐藏.这确实是一种很好的做法,因为结构的内容和行为将来可能会发生变化,而不会影响界面.

实现该目标的一个好方法是使用不完整的类型.

typedef struct foo opaqueType;

现在opaqueType可以构建仅使用指针的接口,而无需用户程序知道内部工作struct foo.

但有时,可能需要静态地(通常在堆栈上)分配此类结构,以解决性能和内存碎片问题.显然,上面的结构,opaqueType是不完整的,所以它的大小是未知的,所以它不能静态分配.

解决方法是分配"shell类型",例如:

typedef struct { int faketable[8]; } opaqueType;

上面的构造强制执行大小和对齐,但不会进一步描述结构真正包含的内容.因此它符合保持"不透明"类型的目标.

它主要起作用.但在一种情况下(GCC 4.4),编译器抱怨它打破了严格别名,并且它生成了错误的二进制文件.

现在,我已经阅读了大量关于严格混叠的内容,所以我想我现在明白这意味着什么.

问题是:有没有办法定义一个opaque类型,它仍然可以在堆栈上分配,而不会破坏严格的别名规则?

请注意,我已经尝试了这篇优秀文章中描述union方法,但它仍然会生成相同的警告.

另请注意,visual,clang和gcc 4.6及更高版本不会抱怨并且可以正常使用此构造.

[编辑]信息补充:

根据测试,问题只发生在以下情况:

  • 私人和公共类型不同.我正在将公共类型转换为.c文件中的私有类型.如果他们是同一个联盟的一部分,那显然无关紧要.公共类型是否包含无关紧要char.
  • 如果私有类型的所有操作都只是读取,则没有问题.只有写入会导致问题.
  • 我还怀疑只有自动内联的函数才会遇到麻烦.
  • 问题仅发生在gcc 4.4 at -O3设置上.-O2很好.

最后,我的目标是C90.也许C99如果真的没有选择.

c stack memory-management opaque-pointers

11
推荐指数
1
解决办法
773
查看次数

不推荐使用'init()':在Swift 3中删除init().使用`nil`

我正在使用此代码.

var audioUnit:AudioUnit = AudioUnit()
Run Code Online (Sandbox Code Playgroud)

但是在Xcode 7.3(Swift 2.2)中,我收到了这个警告.知道为什么吗?我怎么能摆脱它呢?

NB我使用nil然后我的程序崩溃了.

截图

opaque-pointers audiounit ios swift swift2

10
推荐指数
1
解决办法
2491
查看次数

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

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

struct {
    int foo;
    double bar;
} baz;
unsigned char bytes[sizeof baz];

// Do things with the baz structure.

memcpy(bytes, &baz, sizeof bytes);

// Do things with the bytes array.
Run Code Online (Sandbox Code Playgroud)

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

struct {
    int foo;
    double bar;
} baz;
unsigned char *bytes = (void *)&baz;

// Do stuff with the baz structure.

// Do things with the bytes array.
Run Code Online (Sandbox Code Playgroud)

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

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

c void-pointers opaque-pointers

7
推荐指数
1
解决办法
570
查看次数

CGColor内部

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

typedef struct CGColor {
        CFRuntimeBase obj;

        CFTypeID colorID;
        CGColorSpaceRef colorSpace;
        CGPatternRef pattern;
        size_t numberOfComponents;
        CGFloat *components;
} *CGColorRef;
Run Code Online (Sandbox Code Playgroud)

(colorID字段由free quartz命名为nextID,但我认为它是IOS的唯一标识,因此它不是一种下一个标识符.)

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

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

调用CGColorGetIdentifier的堆栈;(希望能帮助推断colorID)

0   com.apple.CoreGraphics CGColorGetIdentifier + 0
1   libRIP.A.dylib          ripc_GetColor + 112
2   libRIP.A.dylib          ripc_DrawGlyphs + 1740
3   com.apple.CoreGraphics  CGContextDelegateDrawGlyphs + 108
4   com.apple.CoreGraphics  drawGlyphs + 284
5   com.apple.CoreGraphics  CGContextShowGlyphsWithAdvances + 208
Run Code Online (Sandbox Code Playgroud)

对于当前的颜色图形上下文操作,ripc_GetColor()计算当前笔触/填充颜色的一些变换,并使用此颜色的referenceID和colorID缓存这些变换.

因此,对于下一个图形上下文操作,ripc_GetColor()将先前缓存的当前引用和colorID值进行比较,以跳过已为最后一个图形上下文操作缓存的颜色转换.

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

但是,标识符可以用于单个对象及其引用,因此仅比较ID就足够了.但是,使用了refs和id.我不认为工程师忽视了这么简单和至关重要的事情.

所以,我试图找出比较id和refs的必要性,同时只比较id就足够了.

是否遗留了以前的方法,所以不能完全放弃?

c core-foundation opaque-pointers ios

6
推荐指数
1
解决办法
600
查看次数

使用pimpl移动类将无法编译

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

如果Impl的声明被移动到它工作的标题,我的问题是如何将析构函数调用为好,所以它似乎不是类型不完整,但移动时出现问题.

档案:C.hpp

#include <memory>

class Impl;


class C
{
public:
    C();
    ~C();

    C(C&&) = default;
    C& operator=(C&&) = default;

    std::unique_ptr<Impl> p;
};
Run Code Online (Sandbox Code Playgroud)

档案C.cpp

#include "C.hpp"
#include <iostream>

using namespace std;

class Impl
{
public:
    Impl() {}
    virtual ~Impl() = default;
    virtual void f() = 0;
};

class CImpl: public Impl
{
public:
    ~CImpl()
    {
        cout << "~CImpl()" << endl;
    }
    void f()
    {
        cout << "f()" << endl;
    }

};


C::C():
    p(new CImpl())
{}

C::~C()
Run Code Online (Sandbox Code Playgroud)

file:main.cpp

#include <iostream>
#include …
Run Code Online (Sandbox Code Playgroud)

c++ pimpl-idiom opaque-pointers c++11

6
推荐指数
1
解决办法
313
查看次数

unique_ptr 到不透明结构?(C++)

库定义了不透明的数据类型:

\n\n
struct OpaqueStruct;\n
Run Code Online (Sandbox Code Playgroud)\n\n

并且客户端代码必须获取并释放OpaqueStruct*. 我可以访问库源。

\n\n

不幸的是,既不能存储该指针shared_ptr,也unique_ptr不能存储该指针,从而出现错误: invalid application of \xe2\x80\x98sizeof\xe2\x80\x99 to incomplete type

\n\n

我能想到的最好的办法就是从这篇文章中借用finally守卫

\n\n

如何将 RAII 用于不透明结构指针?

\n

c++ opaque-pointers c++11 c++14

6
推荐指数
1
解决办法
2976
查看次数