【问题标题】:Can you make an Objective-C++ subclass of a C++ class你能做一个 C++ 类的 Objective-C++ 子类吗
【发布时间】:2012-04-04 19:15:10
【问题描述】:

我正在开发的多平台应用程序使用单个 C++ 类的不同子类,具体取决于其运行的平台。我可以在不更改超类的情况下将 OS X 子类设为 Objective-C++ (.mm) 文件吗?

编辑:更多细节

项目现在包含这个文件层次结构:

* VideoDriver.cpp   - (superclass)
  - VideoDriver_OSX.cpp - (subclass, contains Mac implementation)
  - VideoDriver_win.cpp - (subclass, contains Windows implementation)
  - VideoDriver_X11.cpp - (subclass, contains Linux implementation)

简而言之,我希望能够在 VideoDriver_OSX 实现中使用 Core Animation 和其他 Cocoa 库。将其更改为 Objective-C++ 文件 (VideoDriver_OSX.mm) 允许我使用这些 Cocoa 库,但现在尝试实例化 VideoDriver_OSX 对象的代码行(在不同的文件中)会在运行时导致此动态链接器错误:

dyld: lazy symbol binding failed: Symbol not found: __ZN15VideoDriver_OSXC1EP10gui_info_sP6CPFifoI17DecodedVideoFrameE

这似乎与 C++ name mangling 有关,但我不知道如何解决它。我真的很感谢你的帮助,伙计们。

【问题讨论】:

  • 有趣的是,我之前问过一个类似的问题,并举例说明了如何做到这一点:stackoverflow.com/questions/10014684/…
  • “我可以让 OS X 子类成为 Objective-C++ (.mm) 文件吗”
  • 请贴出导致错误的代码行。
  • m_driver = new VideoDriver_OSX(m_gui_info, m_fifo_in);
  • 调用的文件是什么类型的? .mm 还是 .cpp?

标签: c++ objective-c macos


【解决方案1】:

.cpp 文件重命名为.mm 将在很多情况下起作用,因为Objective-C 对象系统、语法和运行时或多或少不同于C++ 对象系统、语法和运行时。当您将 .cpp 重命名为 .mm 时,它不会神奇地将 C++ 对象转换为 Objective-C 对象,它们仍然是 C++ 对象。 .mm 文件的作用是允许您在同一个文件中同时使用 Objective-C 和 C++ 对象,这是因为 Objective-C 和 C++ 之间几乎没有对象系统、语法或运行时相互冲突。

如果您在 Objective-C 代码中使用名为 new 等的变量,转换为 Objective-C++ 可能会导致问题,因为这是 C++ 中的关键字。同样,在编译为 Objective-C++ 时,Objective-C 中的任何关键字都不能在 C++ 代码中使用。

【讨论】:

  • 从技术上讲,objective-c++中没有objective-c类,它们都是objective-c++类。更清楚地说,这意味着当你编译objective-c++时,“objective”类编译为C++类,而不是C结构等。
  • @mydogisbox:你在开玩笑吗?你到底是从哪里听到的?您被严重误导了,否则请通过在 Objective-C 运行时或 clang 编译器源中指出来向我证明这一点。
  • @mydogisbox:当编译为 Objective-C++ 时,Objective-C 类不会编译为 Objective-C 类以外的任何东西,否则它们不会与现有的 non 互操作-Objective-C++ 类。
  • 现在将其更改为 .mm 文件可以让我在类中使用 Objective-C,但是当我尝试实例化 .mm 文件描述的对象时,我遇到了动态链接器错误。这可以修复吗?
  • @mydogisbox:不,它仍然是 Objective-C 对象,即使它在其方法中使用 C++ 代码。 Objective-C 语言定义与 C++ 语言定义“兼容”,即 Objective-C 和 C++ 语言定义的联合不包含冲突。如果 C++ 和 C 互操作没有问题,那么 C++ 中就不需要 extern "C" {}。在 Objective-C++ 中不需要它,因为在 Objective-C++ 下编译时,Objective-C 对象保持为 Objective-C 对象。所有“Objective-C++”的意思是你可以在同一个源文件中编译Objective-C和C++。
【解决方案2】:

“我能否在不更改超类的情况下将 OS X 子类设为 Objective-C++ (.mm) 文件?”

是的。假设通过“子类化一个 Objective-C++ ... 文件”,您的意思是您的 Objective-C++ 代码中有一个 C++ 类,是 .cpp 文件中的 C++ 类的子类。如果你想使用objective-c++ 类作为你的C++ 类的子类,那么你就不走运了。

【讨论】:

    【解决方案3】:

    没有Objective-C++ 对象这样的东西。在 Objective-C++ 文件中,您可以制作/使用 Objective-C 对象或 C++ 对象。桥接的最佳选择是组合 - 如果您要移植 C++ 框架以在 Objective-C 中使用,请创建对象:

    • 具有 C++ 对象的实例
    • 实现重定向到 C++ 对象的方法。

    根据 API 的简单程度,这可能不是一件容易的事!

    【讨论】:

    • "没有 Objective-C++ 对象这样的东西。"是不正确的。在objective-c++中没有objective-c类,只有C++和objective-c++类。
    • 我不同意。您可以在纯 Objective-C 代码中使用在 Objective-C++ 文件中定义的类,而 Objective-C 不了解 Objective-C++。所以那个类是一个Objective-C类。在这个类的实现中可以使用 C++ 对象这一事实并不影响接口。
    • 当然可以。就像您可以在 C 实现文件中使用 C++ 结构一样(因为这是 Objective-c 类的基础)。这并没有改变在 C++ 代码中定义的“目标”类是 C++ 而不是 C 的扩展。
    猜你喜欢
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多