在 Objective-C 中前向声明一个结构体

发布于 2025-01-01 16:27:48 字数 237 浏览 1 评论 0原文

我正在创建一个协议,我定义的方法的参数之一是 CMTime*。我想转发声明 CMTime 而不是包含它。但是,我尝试过 @class CMTime ,它抱怨它在其他地方被重新定义为不同类型的符号。文档说它是一个结构。我已经尝试将其声明为

struct CMTime;

,但它仍然抱怨它不知道它是什么。

有什么想法我做错了吗?

I'm creating a protocol, and one of the parameters to a method I'm defining is a CMTime*. I would like to forward declare CMTime as opposed to including it. However, I've tried @class CMTime and it complains that it is redefined elsewhere as a different type of symbol. Documentation says it's a struct. I've tried forward declaring it as

struct CMTime;

but it still is complaining that it doesn't know what it is.

Any ideas what I'm doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

二手情话 2025-01-08 16:27:48

在这方面,编译为 ObjC 的源代码与 C 具有相同的规则。

在这方面,编译为 ObjC++ 的源代码与 C++ 具有相同的规则。

@class MONClass; 是 ObjC 类型的前向声明。不要将其用于结构。

struct t_mon_struct; 是一个命名 C 或 C++ 结构体的前向声明。不要将其用于 ObjC 类型。从技术上讲,编译器还允许您将 C++ 类转发声明为结构(当然前提是该类也在全局命名空间中声明)。

因此,语义的根源都归结为 C(假设这是 ObjC 翻译)。我现在不再提及 ObjC 和 C++。

这里有一些常见的复杂性来源:

  • 结构体命名空间
  • 结构体的声明
  • 避免了标签的多个定义

struct t_mon_struct; 是标记结构体的前向声明。具体来说,即其名称存在于结构命名空间中。

存在于结构命名空间中的标记结构:

struct t_mon_struct { int a; };

在全局命名空间中具有 typedef 的匿名结构:

typedef struct { int a; } t_mon_struct;

在全局命名空间中具有 typedef 的标记结构:

typedef struct t_mon_struct { int a; } t_mon_struct;

CMTime 声明如下:

typedef struct
{
    CMTimeValue    value;
    CMTimeScale    timescale;
    CMTimeFlags    flags;
    CMTimeEpoch    epoch;
} CMTime;

具体而言,全局 typedef标签 CMTime 绑定到结构命名空间中的匿名结构,除非其声明可见,否则不能被引用。

如果 CMTime 已声明:

typedef struct CMTime
{
    CMTimeValue    value;
    CMTimeScale    timescale;
    CMTimeFlags    flags;
    CMTimeEpoch    epoch;
} CMTime;

那么您可以通过使用前向声明 struct CMTime 来获得:

struct CMTime;
void foo(struct CMTime*);

由于它没有以这种方式声明,因此您需要 #包含它的声明,或者设计一个解决方法。

当结构体的 typedef 与其标签不同时,情况会更加复杂。您不能绑定或重新声明 typedef(在 C 中)。但是,您可以通过使用结构命名空间中的名称来绕过它——一些库作者认为该名称是私有的。

A source compiled as ObjC has the same rules as C in this regard.

A source compiled as ObjC++ has the same rules as C++ in this regard.

@class MONClass; is a forward declaration of an ObjC type. Do not use it for structs.

struct t_mon_struct; is a forward declaration of a named C or C++ struct. Do not use it for ObjC types. Technically, the compiler allows you to also forward declare a C++ class as a struct (provided of course the class is also declared in the global namespace).

Thus, the root of the semantics all boil down to C (assuming this is an ObjC translation). I'll stop mentioning ObjC and C++ now.

There are some common sources of complexity here:

  • the struct namespace
  • the struct's declaration
  • avoiding multiple definitions of labels

struct t_mon_struct; is a forward declaration of a tagged struct. Specifically, that is whose name exists in the struct namespace.

a tagged struct which exists in the struct namespace:

struct t_mon_struct { int a; };

an anonymous struct with a typedef in the global namespace:

typedef struct { int a; } t_mon_struct;

a tagged struct with a typedef in the global namespace:

typedef struct t_mon_struct { int a; } t_mon_struct;

CMTime is declared as follows:

typedef struct
{
    CMTimeValue    value;
    CMTimeScale    timescale;
    CMTimeFlags    flags;
    CMTimeEpoch    epoch;
} CMTime;

Specifically, the global typedef label CMTime is bound to an anonymous struct in the struct namespace, and may not be referenced unless its declaration is visible.

Had CMTime been declared:

typedef struct CMTime
{
    CMTimeValue    value;
    CMTimeScale    timescale;
    CMTimeFlags    flags;
    CMTimeEpoch    epoch;
} CMTime;

then you could have gotten by using a forward declaration struct CMTime:

struct CMTime;
void foo(struct CMTime*);

Since it wasn't declared that way, you'll need to #include its declaration, or devise a workaround.

The complications worsen when the the struct's typedef is distinct from its tag. You can't bind to or redeclare a typedef (in C). However, you can sneak around it by using the name in the struct namespace -- which some library authors consider as being private.

只有一腔孤勇 2025-01-08 16:27:48

只需在结构之前添加 typedef 对我来说就可以了。

typedef struct CMTime;

Just adding typedef before the struct does the trick for me.

typedef struct CMTime;

如果您希望具有前向声明的文件了解结构的内容,则它们需要导入定义它的标头(它可以位于多个位置)。如果您不需要访问结构体的属性,您可以转发声明该结构体,但这就是它的范围。

If you want the files which have the forward declaration to know about the contents of the struct, they need to either import a header (it can be in multiple places) where it is defined. You can forward declare a struct if you do not need to access its properties, but that is the extent of it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文