是适用于iOS的metasyntactic静态库。 。 。
http://code.google.com/p/metasyntactic/wiki/ProtocolBuffers
。 。 。兼容常规的旧C ++编译的原型文件?我 不 想要使用生成Obj-C的捆绑编译器。
有没有办法编译Google for iOS提供的库?
答案 0 :(得分:19)
确定。在这种情况下,似乎不需要metasyntactic库(或任何其他第三方库)。您只需将Google源代码直接添加到项目中即可。我在谷歌讨论组中找到了Nicola Ferruzzi的以下答案。 。
原来的答案就在这里。 。 。
http://groups.google.com/group/protobuf/browse_thread/thread/ca4218d7db144252
此答案的内容包含在下面,图片可以作为永久记录...
修改强>
自从今晚第一次再次尝试这个以来,除了下面列出的步骤之外,我还需要更多的步骤(这适用于protobuf 2.5.0)。
find . -name "*unittest*" -exec rm -rf {} \;
中的shell中的以下命令testing
#include <google/protobuf/testing/googletest.h>
stringprintf.cc
我在我的应用程序中使用最新版本..你真的不需要直接objc 如果您熟悉C ++,那么只有一点可以支持 你必须从std :: string传递给NSData,反之亦然。而且它 很简单。
编译和测试我发现的最简单方法就是导入 在我自己的项目中的整个谷歌目录:)(第二次你可以 制作你自己的框架但是为了测试这个程序就行了)
- 下载最新版本
- autogen配置和make就像你刚刚为macosx构建(你需要命令行工具)。这样你最终会使用protoc 二进制文件和macosx库(你不需要)
- 打开您的Xcode iOS项目
- 将“新文件”添加到您的项目并选择google目录
- 将google标头的目录添加到其他包含目录
- 将config.h从protobuffer src目录添加到您的应用
来自google群组的- 删除包含unitest :)的所有内容。
来自google群组的- 删除编译器和java的东西;
您应该能够在没有任何链接错误的情况下进行编译。为你带来 这是我直接编译的想法
然后你可以使用protoc为你的生成c ++源文件 协议。要将它们与objc一起使用,您必须将源重命名为 文件“mm”然后你可以做类似的事情
切换到NSDATA
假设您的邮件名为Packet
- (NSData *)getDataForPacket:(Packet *)packet { std::string ps = packet->SerializeAsString(); return [NSData dataWithBytes:ps.c_str() length:ps.size()];
从NSDATA读取
- (Packet *)getPacketFromNSData:(NSData *)data { char raw[[data length]]; Packet *p = new Packet; [data getBytes:raw length:[data length]]; p->ParseFromArray(raw, [data length]); return p; }
答案 1 :(得分:14)
您可以使用Cocoapods将对Google协议缓冲区的支持添加到Xcode 5项目中,方法是将以下行添加到您的Podfile中。
pod 'GoogleProtobuf', '~> 2.5.0'
这会将protobuf代码的C ++版本放入到项目的Pod中。它还会在项目的protoc
文件夹中添加Pods/GoogleProtobuf/bin/protoc
编译器。
您可以在项目中创建自定义构建规则,自动将.proto
文件转换为.ph.{h,cc}
个文件。我是这样做的:
将构建规则设置为“处理名称匹配的源文件:* .proto使用自定义脚本”。该脚本应包括以下内容:
cd ${INPUT_FILE_DIR}
${SRCROOT}/Pods/GoogleProtobuf/bin/protoc --proto_path=${INPUT_FILE_DIR} ${INPUT_FILE_PATH} --cpp_out=${INPUT_FILE_DIR}/cpp
设置输出文件以包含以下内容:
$(INPUT_FILE_DIR)/cpp/$(INPUT_FILE_BASE).pb.h
$(INPUT_FILE_DIR)/cpp/$(INPUT_FILE_BASE).pb.cc
您项目中包含的任何.proto
文件现在将自动转换为C ++,然后作为构建的一部分进行编译。
答案 2 :(得分:12)
编辑:我之前已经回答了这个问题,但被主持人删除了。所以我已经包含了教程中的一些代码。
与上面发布的答案几乎相同的教程 - Using Google Protocol Buffers in Objective-C on iOS and the Mac
按照learnvst的回答中给出的步骤,并参考评论中的陷阱。我遵循完全相同的步骤,除了
将google标头目录添加到其他包含目录中 我在标题搜索路径中添加了 src / 目录,而不是google目录。
此外,当我#import xyz.pb.h
时,项目没有建成。当我将 .m 文件重命名为 .mm 时,我能够构建。本教程中非常巧妙地提到了这一点:P。
基本上,导入任何 .pb.h 文件的任何 .m 文件都应重命名,扩展名为 .mm
以下是教程中的一些内容 -
PROTO文件
package kotancode;
enum ZombieType {
SLOW = 0;
FAST = 1;
}
message ZombieSighting {
required string name = 1;
required double longitude = 2;
required double latitude = 3;
optional string description = 4;
required ZombieType zombieType = 5 [default = SLOW];
}
ZombieSightingMessage.h
// -- ZombieSightingMessage.h - note my C++ object is not in the public interface.
#import <Foundation/Foundation.h>
@interface ZombieSightingMessage : NSObject
- (void)doSomething;
@end
<强> ZombieSightingMessage.mm 强>
// -- ZombieSightingMessage.mm
#import <UIKit/UIKit.h>
#import "ZombieSightingMessage.h"
#import "zombie.pb.h"
@implementation ZombieSightingMessage
- (void)doSomething {
// Doing random stuff with a UIView here to show the mixing
// of C++ and Objective-C/Cocoa syntax in the same file...
UIView *uiView = [[UIView alloc] init];
[uiView setCenter:CGPointMake(20, 10)];
// instantiate my protobuf-generated C++ class.
kotancode::ZombieSighting *zombieSighting = new kotancode::ZombieSighting();
zombieSighting->set_name("Kevin");
zombieSighting->set_description("This is a zombie");
zombieSighting->set_latitude(41.007);
zombieSighting->set_longitude(21.007);
zombieSighting->set_zombietype(kotancode::ZombieType::FAST);
// Some small tomfoolery required to go from C++ std::string to NSString.
std::string x = zombieSighting->DebugString();
NSString *output = [NSString stringWithCString:x.c_str() encoding:[NSString defaultCStringEncoding]];
NSLog(@"zombie: %@", output);
// Instantiate another zombie from the previous zombie's raw bytes.
NSData *rawZombie = [self getDataForZombie:zombieSighting];
kotancode::ZombieSighting *otherZombie = [self getZombieFromData:rawZombie];
// Dump the second zombie so we can see they match identically...
NSString *newOutput = [NSString stringWithCString:otherZombie->DebugString().c_str() encoding:[NSString defaultCStringEncoding]];
NSLog(@"other zombie: %@", newOutput);
// Grimace all you want, but this is C++ and we need to clean up after ourselves.
free(zombieSighting);
free(otherZombie);
}
// Serialize to NSData. Note this is convenient because
// we can write NSData to things like sockets...
- (NSData *)getDataForZombie:(kotancode::ZombieSighting *)zombie {
std::string ps = zombie->SerializeAsString();
return [NSData dataWithBytes:ps.c_str() length:ps.size()];
}
// De-serialize a zombie from an NSData object.
- (kotancode::ZombieSighting *)getZombieFromData:(NSData *)data {
int len = [data length];
char raw[len];
kotancode::ZombieSighting *zombie = new kotancode::ZombieSighting;
[data getBytes:raw length:len];
zombie->ParseFromArray(raw, len);
return zombie;
}
@end
编辑:我正在使用Xcode 4.5。即使我按照所有步骤操作,我也会收到链接器错误。
未找到架构i386的符号
由于这个原因,我无法在模拟器上运行代码。但它适用于实际设备
答案 3 :(得分:1)
我想根据实际问题,我的评论值得张贴作为答案:
我正在使用由Booyah
提供的本机Obj代码生成的略微修改版本它支持重复的字段,但为了使用ObjC快速枚举,您需要将PBArray类型(基本上是一个类型化的c缓冲区)转换为它所代表的NSObject数组 - 无论是NSNumber还是protobuf消息对象。您可以在this change中看到更新的快速枚举代码的示例:。您还可以在PBArray上为toObjects添加一个类别。
我只是使用-fno-objc-arc
标记生成的代码,但您可以从booyah pull requests获得arc和2.5支持。
方向非常适合设置,但是如果人们想要更明确的指示我使用的类别,我如何构建protobuf-objc插件,如何获得对类前缀的支持(例如IXMyProtoMessage而不是MyProtoMessage)或者我如何生成代码让我知道,我会尽量留出时间写一篇文章。我正在使用&gt; 50个具有大量跨项目依赖关系的proto文件。
库的一个弱点是它不包含生成的代码上典型的Protobuf反射API,所以做一些事情就像将消息转换为NSDictionary一样,必须用objC运行时做一些hacky的东西(代码没有'遵循典型的KV合规性)或者从具有反射api的protos编写自定义代码生成器(我使用python + jinja2执行此操作)。或者 - 更好的和类似的难度,将反射apis添加到代码生成器;)。