我可以在编译和链接中将C ++ main函数和类从Objective-C和/或C例程中分离出来吗?
我有一个小型的C ++应用程序,我导入了Objective-C类。 它可以用作Objective-C ++文件.mm,但是包含可能最终包含一些Objective-C头文件的头文件的任何C ++文件都必须重命名为适合GCC驱动程序的.mm扩展名。
有没有办法为Objective-C类编写纯粹的C ++包装器,或者我可以以某种方式将Objective-C对象分开,并将它们分开链接起来? 也许即使Objective-C类成为一个小型库,我可以在编译时静态地重新链接?
问题是这个代码是跨平台的,在通常不使用Objective-C(即不是Mac)的系统上编译更加困难。 尽pipe预处理器命令限制了在Windows或Linux上Objective-C代码的任何实现,但原始代码仍然具有.mm扩展名,而GCC仍然将代码视为Objective-C ++。
通常你只需用C ++类包装你的Objective-C类,例如使用不透明的指针并将调用转换为C ++方法到Objective-C方法。
这样,您的便携式C ++源码永远不需要看到任何Objective-C包含,理想情况下,您只需要在不同平台上交换包装器的实现文件。
例:
// c++ header: class Wrapper { struct Opaque; Opaque* opaque; // ... public: void f(); }; // Objective-C++ source on Mac: struct Wrapper::Opaque { id contained; // ... }; void Wrapper::f() { [opaque->contained f]; } // ...
是的,如果你知道一些技巧,那么这两种方法都是可能的:
1)“id”types实际上是在普通的C头文件中定义的。 所以你可以做到以下几点:
在你的标题中:
#include <objc/objc.h> class MyWindow { public: MyWindow(); ~MyWindow(); protected: id mCocoaWindow; };
在你的实现(.mm)中:
#include "MyWindow.h" #include <Cocoa/Cocoa.h> MyWindow::MyWindow() { mCocoaWindow = [[NSWindow alloc] init]; } MyWindow::~MyWindow() { [mCocoaWindow release]; mCocoaWindow = nil; }
2)有两个预处理常量可以用来排除C ++ / ObjC特定的代码,当一个源文件包含它们是两个之一,但不是ObjC ++:
#if __OBJC__ // ObjC code goes here. #endif /* __OBJC__*/ #if __cplusplus // C++ code goes here. #endif
只要小心,你不能只用#ifdef添加/删除ivars或虚拟方法,这将创build两个具有不同内存布局的类,并以非常怪异的方式使你的应用程序崩溃。
3)您可以使用指向结构体的指针而不声明其内容:
在你的标题中:
@interface MyCppObjectWrapper : NSObject { struct MyCppObjectWrapperIVars *ivars; // This is straight ObjC, no ++. } @end
在您的实施文件(.mm)中:
struct MyCppObjectWrapperIVars { std::string myCppString1; std::string myCppString2; std::string myCppString3; }; @implementation MyCppObjectWrapper -(id) init { if(( self = [super init] )) { ivars = new MyCppObjectWrapperIVars; } return self; } -(void) dealloc { delete ivars; ivars = NULL; [super dealloc]; } @end
这将使您的标题简单的标准C或ObjC,而你的实现文件获取调用所有ivars的构造函数/析构函数,而不必创build/删除每个堆作为一个对象。
这仅仅是Mac的一部分,但是这意味着你可以将ObjC的东西保存在你的头文件中,或者至less在从C ++可移植层的Mac实现的跨平台客户端文件中进行编译时进行编译。
- 界面生成器中的“宽度等于高度”约束
- 如何使xib兼容iphone 5和iphone 4设备
- build议停止Gradle构build的方法
- Xcode警告:“输出文件的多个构build命令”
- Xcode 8不能存档“命令/ usr / bin / codesign失败,退出代码1”
- Android Build失败 – java.lang.IllegalArgumentException:已经添加:Lcom / google / api / client / escape / CharEscapers;
- 如何以编程方式创build一个基本的UIButton?
- 如何设置Cmake来生成只有标题的项目?
- 我如何得到Git的提交计数?