我想使用谷歌协议缓冲区存储数据(另一种序列化格式也可以),然后有一个用于浏览该数据的UI.是否有允许我这样做的C++框架/ API?
例如,它可以使用protobuf的反射接口,然后将数据填入Qt的QTableView(或其他工具包).我可以自己编写这样的代码 - 但是,我更愿意重用现有代码,这就是我在这里寻求建议的原因!
或者是否有更多通用的UI工具包可以显示可通过某些反射API访问的数据?
使用以下代码时,我对链接器错误感到困惑:
// static_const.cpp -- complete code
#include <vector>
struct Elem {
static const int value = 0;
};
int main(int argc, char *argv[]) {
std::vector<Elem> v(1);
std::vector<Elem>::iterator it;
it = v.begin();
return it->value;
}
Run Code Online (Sandbox Code Playgroud)
但是,这在链接时失败 - 不知何故,它需要有一个静态const"值"的符号.
$ g++ static_const.cpp
/tmp/ccZTyfe7.o: In function `main':
static_const.cpp:(.text+0x8e): undefined reference to `Elem::value'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这与-O1或更好的编译很好; 但对于更复杂的情况,它仍然失败.我使用的是gcc版本4.4.4 20100726(Red Hat 4.4.4-13).
任何想法我的代码可能有什么问题?
我想在几个进程之间使用共享内存,并希望能够继续使用原始指针(和stl容器).
为此,我使用映射在固定地址的共享内存:
segment = new boost::interprocess::managed_shared_memory(
boost::interprocess::open_or_create,
"MySegmentName",
1048576, // alloc size
(void *)0x400000000LL // fixed address
);
Run Code Online (Sandbox Code Playgroud)
选择这个固定地址的好策略是什么?例如,我应该使用一个相当高的数字来减少我用完堆空间的可能性吗?
是否可以将前向声明的类的成员函数声明为朋友?我正在尝试执行以下操作:
class BigComplicatedClass;
class Storage {
int data_;
public:
int data() { return data_; }
// OK, but provides too broad access:
friend class BigComplicatedClass;
// ERROR "invalid use of incomplete type":
friend void BigComplicatedClass::ModifyStorage();
};
Run Code Online (Sandbox Code Playgroud)
因此,目标是(i)将友元声明限制为单个方法,以及(ii)不包括复杂类的定义以减少编译时间.
一种方法可能是添加一个充当中间人的类:
// In Storage.h:
class BigComplicatedClass_Helper;
class Storage {
// (...)
friend class BigComplicatedClass_Helper;
};
// In BigComplicatedClass.h:
class BigComplicatedClass_Helper {
static int &AccessData(Storage &storage) { return storage.data_; }
friend void BigComplicatedClass::ModifyStorage();
};
Run Code Online (Sandbox Code Playgroud)
然而,这似乎有点笨拙...所以我认为必须有一个更好的解决方案!
我尝试使用奇怪的重复模板模式(CRTP)并提供其他类型参数:
template <typename Subclass, typename Int, typename Float>
class Base {
Int *i;
Float *f;
};
...
class A : public Base<A, double, int> {
};
Run Code Online (Sandbox Code Playgroud)
这可能是一个错误,更合适的超类Base<A, double, int>- 尽管这个参数顺序不匹配并不是那么明显.如果我可以在typedef中使用name的含义,那么这个bug会更容易看到:
template <typename Subclass>
class Base {
typename Subclass::Int_t *i; // error: invalid use of incomplete type ‘class A’
typename Subclass::Float_t *f;
};
class A : public Base<A> {
typedef double Int_t; // error: forward declaration of ‘class A’
typedef int Double_t;
};
Run Code Online (Sandbox Code Playgroud)
但是,这不能在gcc 4.4上编译,报告的错误是作为上面的注释给出的 - 我认为原因是在创建A之前,它需要实例化Base模板,但这又需要知道A.
使用CRTP时是否有传递"命名"模板参数的好方法?
我有一个带有两个NIC(eth0和eth1)的linux服务器,并且在"ip route"中将eth0设置为默认值.现在我想在eth1上接收多播数据包.我在路由表中添加了"224.0.20.0/24 dev eth1 proto static scope link",并按如下方式连接:
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
// port 12345, adress INADDR_ANY
bind(sock, &bind_addr, sizeof(bind_addr));
// multicast address 224.0.20.100, interface address 10.13.0.7 (=eth1)
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imreq, sizeof(imreq));
Run Code Online (Sandbox Code Playgroud)
根据ip maddr它在正确的接口上连接到该组,并tshark -i eth1显示我实际上正在获取多播数据包.
但是,我在呼叫时没有收到任何数据包recvfrom(sock).如果我将"ip route default"设置为eth1(而不是eth0),我会通过recvfrom获取数据包.这是我的代码或我的网络设置的问题,这样做的正确方法是什么?
(更新)解决方案: caf暗示这可能是同样的问题; 确实:做完之后echo 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter我现在可以收到组播数据包了!