Dear reader,
Hereby I supply a patch for protobuf-2.4.1 which implements the ability to
use const method callbacks.
Kind regards,
Ralph Langendam
Op donderdag 13 september 2012 14:37:03 UTC+2 schreef Ralph het volgende:
>
> Dear reader,
>
> It has come to my attention that the callback mechanism of protobuf 2.4.1
> doesn't support the usage of const class methods, as the following example
> demonstrates:
>
> class C {public:
> Closure* GetClosure () const {
> return NewCallback<C> (this, &C::RunCallback);
> }
>
> void RunCallback () const {
> }
> };
>
> I propose the solution in the attachment for all method callbacks. I've only
> made an implementation for MethodClosure0, but the others are pretty similar.
>
> Kind regards,
>
> Ralph Langendam
>
>
>
--
You received this message because you are subscribed to the Google Groups
"Protocol Buffers" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/protobuf/-/Is-cee-y_8MJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/protobuf?hl=en.
diff -u -r protobuf-2.4.1.orig/src/google/protobuf/compiler/cpp/cpp_service.cc protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_service.cc
--- protobuf-2.4.1.orig/src/google/protobuf/compiler/cpp/cpp_service.cc 2012-04-06 10:32:09.000000000 +0200
+++ protobuf-2.4.1/src/google/protobuf/compiler/cpp/cpp_service.cc 2012-09-19 11:29:19.000000000 +0200
@@ -89,7 +89,7 @@
"\n"
"// implements Service ----------------------------------------------\n"
"\n"
- "const ::google::protobuf::ServiceDescriptor* GetDescriptor();\n"
+ "const ::google::protobuf::ServiceDescriptor* GetDescriptor() const;\n"
"void CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
" ::google::protobuf::RpcController* controller,\n"
" const ::google::protobuf::Message* request,\n"
@@ -180,7 +180,7 @@
" return $classname$_descriptor_;\n"
"}\n"
"\n"
- "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() {\n"
+ "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() const {\n"
" protobuf_AssignDescriptorsOnce();\n"
" return $classname$_descriptor_;\n"
"}\n"
diff -u -r protobuf-2.4.1.orig/src/google/protobuf/service.h protobuf-2.4.1/src/google/protobuf/service.h
--- protobuf-2.4.1.orig/src/google/protobuf/service.h 2012-04-06 10:32:11.000000000 +0200
+++ protobuf-2.4.1/src/google/protobuf/service.h 2012-09-18 09:28:55.000000000 +0200
@@ -136,7 +136,7 @@
};
// Get the ServiceDescriptor describing this service and its methods.
- virtual const ServiceDescriptor* GetDescriptor() = 0;
+ virtual const ServiceDescriptor* GetDescriptor() const = 0;
// Call a method of the service specified by MethodDescriptor. This is
// normally implemented as a simple switch() that calls the standard
diff -u -r protobuf-2.4.1.orig/src/google/protobuf/stubs/common.h protobuf-2.4.1/src/google/protobuf/stubs/common.h
--- protobuf-2.4.1.orig/src/google/protobuf/stubs/common.h 2012-04-06 10:32:13.000000000 +0200
+++ protobuf-2.4.1/src/google/protobuf/stubs/common.h 2012-09-19 11:29:19.000000000 +0200
@@ -865,20 +865,30 @@
class MethodClosure0 : public Closure {
public:
typedef void (Class::*MethodType)();
+ typedef void (Class::*CMethodType)() const;
MethodClosure0(Class* object, MethodType method, bool self_deleting)
- : object_(object), method_(method), self_deleting_(self_deleting) {}
+ : object_(object), cobject_(0), method_(method), cmethod_(0), self_deleting_(self_deleting) {}
+ MethodClosure0(const Class* object, CMethodType cmethod, bool self_deleting)
+ : object_(0), cobject_(object), method_(0), cmethod_(cmethod), self_deleting_(self_deleting) {}
~MethodClosure0() {}
void Run() {
bool needs_delete = self_deleting_; // read in case callback deletes
- (object_->*method_)();
+ if (object_) {
+ (object_->*method_)();
+ }
+ else { // cobject_
+ (cobject_->*cmethod_)();
+ }
if (needs_delete) delete this;
}
private:
Class* object_;
+ const Class* cobject_;
MethodType method_;
+ CMethodType cmethod_;
bool self_deleting_;
};
@@ -998,10 +1008,22 @@
// See Closure.
template <typename Class>
+inline Closure* NewCallback(const Class* object, void (Class::*method)() const) {
+ return new internal::MethodClosure0<Class>(object, method, true);
+}
+
+// See Closure.
+template <typename Class>
inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) {
return new internal::MethodClosure0<Class>(object, method, false);
}
+// See Closure.
+template <typename Class>
+inline Closure* NewPermanentCallback(const Class* object, void (Class::*method)() const) {
+ return new internal::MethodClosure0<Class>(object, method, false);
+}
+
// See Closure.
template <typename Arg1>
inline Closure* NewCallback(void (*function)(Arg1),
Only in protobuf-2.4.1/vsprojects: libprotobuf.vcxproj
Only in protobuf-2.4.1/vsprojects: libprotobuf.vcxproj.filters