Just to be clear: I am quite an amateur in C++ coding.
Presently, I am using Protobuff to serialize and exchange data between a c++ and a java model. Since both the models use different variables name for the same scientific terminology (for daily river drainage, c++ model uses dailyRiverDrianage and java uses dailyRdrainage). I used a new variable in protoc to define a variable being share.
My question is which is the best way to link both(protoc variable and model variable). Can't change the variable name in Java or C++
Basically you need an intermediate layer on one side to have a consistent mapping to the proto files. Do it on the Java side since you are more comfortable in that language. That intermediate layer would map from what ever is on the Java to the Java variables with different names.
Edit:
C++ side
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
}
Java Side
message Individual {
required string fullName = 1;
required int32 personal_id = 2;
optional string personal_email = 3;
}
Send the data to the from C++ side to Java side. Generate the same Person message unit on Java side and deserialize the message get the data out and copy (map).
name -> fullName
id -> personal_id
email -> personal_email
This is then your decoder/converter unit that you can tinker around as the interfaces change.
Related
I'd like to create a Java-based SDK that can be invoked from Flutter, the Flutter side needs to plug into the SDK by providing callbacks to be executed at different stages of the processing, ideally something like:
Future<Result> = doPayment(
amount: 100.00,
currency: 'USD',
onPasscodeEntry: () => _renderInputBox(),
onValidation: () => _doValidation()
);
the processing itself takes some time etc so a Future<PaymentResult> pattern makes sense, the application should react to some points of the processing, so it makes sense to pass in callbacks.
Problems:
how to pass functions to Java code? As far as I can tell all the Java-passable method arguments in Flutter are serializable-ish objects
(less critical/optional) how to return a POJO and handle it in Dart? Judging from the specs I should encode (within Java) the result in a ArrayList/HashMap or as a JSON string and then create the equivalent constructor in Dart that takes in List/Map ? This seems a bit unwieldy, so I'm asking if there's a simpler way, preferably without maintaining a Java & Dart variants of the same object
You can not pass a function.
You can create a map from a function name to a function reference and then pass the function name and look up the function in by name in the map and call it.
You also can't pass a POJO.
You need to serialize it to JSON (or some other supported format) and deserialize it on the other side of the channel. For that you need to have to POJO class implemented in Dart and in Java.
Packages like protobuf or flatbuffer allow to geneerate code for different languages based on an reduced language to specify the data structure.
In Java,
If I had a String already declared and it holds the name of a variable. Can I use that String to access that variable?
For Example
int sample=10;
String test = "sample";
Here,is it possible use the string test to access integer variable sample.
If yes, then how.
Reflection
One of the strongest aspects of Java is the robust reflection API provided by the standard libraries.
Reflection allows you examine and modify the structures and behaviour of classes, methods, and attributes at runtime.
Reflection is, in my opinion, single handedly responsive for the robust Java ecosystem of platforms, frameworks, and JVM languages available today.
Caution
While reflection is powerful and is definitely a part of Java widespread success I caution against using it in many circumstances.
For the most part reflection
is used in software used by other software (frameworks, platforms, languages, etc). Generally when I see someone ask about reflection (especially if they do not call it by name) they are thinking about the problem wrong.
I would definitely like to hear your use case so we can possibly suggest a different way of looking at it.
Sample Code
Below is some psuedo code that illustrates one way to accomplish what you are trying to do. I call it psuedo code because I have not compiled it, and it could likely be optimized.
Before adding it to your project I would like to reiterate that you should post your specific problem so we can analyze it and possibly help you think about it differently.
final String ATTR = "test";
Class<?> clazz = Class.forName("your.fully.qualified.class.name");
Field[] fields = clazz.getFields();
for ( Field field : fields ) {
String name = field.getName();
if ( name == ATTR ) {
Object value = field.get(name);
}
}
I would create a data binding code generator for a specified programming language and for a specified serialization format: given a specification for the structure of data to be serialized or deserialized, the intended code generator should generate the classes (in the specified programming language) that represent the given vocabulary as well as the methods for serialization and deserialization using the specified format. The intended code generator could require the following inputs:
the target programming language, that is the programming language for generating the code;
the target serialization format, that is the serialization format for the data;
the specification of the structure of data to be serialized or deserialized.
Since initially I would like to create a simple code generator, the first version of this software could require only define the specification of the structure of data to be serialized or deserialized, so I choose C# as target programming language and XML as target serialization format.
Essentially, the intended code generator should be a Java software which reads the specification of the structure of data to be serialized or deserialized (this specification must be written in according to a given grammar), and generates the C# classes that represent the given vocabulary: these classes should have the methods for serialization and deserialization in XML format. The purpose of the intended code generator is to generate one or more classes, so that they could be embedded in a C# project.
Regarding the specification of the structure of data to be serialized or deserialized, it could be defined as in the following example:
simple type Message: int id, string content
Given the specification in the above example, the intended code generator could generate the following C# class:
public class Message
{
public int Id { get; set; }
public string Content { get; set; }
public byte[] Serialize()
{
// ...
}
public void Deserialize(byte[] data)
{
// ...
}
}
I read about ANTLR and I believe that this tool is perfect for the just explained purpose. As explained in this answer, I should first create a grammar for the specification of the structure of data to be serialized or deserialized.
The above example is very simple, because it defines only a simple type, but the specification of the structure of data could be more complex, so we could have a compound type which includes one or more simple types, or lists, etc., like in the following example:
simple type LogInfo: DateTime time, String message
simple type LogSource: String class, String version
compound type LogEntry: LogInfo info, LogSource source
Moreover, the specification of the data could include also one or more constraints, like in the following example:
simple type Message: int id (constraint: not negative), string content
In this case, the intended code generator could generate the following C# class:
public class Message
{
private int _id;
private string _content;
public int Id
{
get { return _id; }
set
{
if (value < 0)
throw new ArgumentException("...");
_id = value;
}
}
public string Content
{
get { return _content; }
set { _content = value; }
}
public byte[] Serialize()
{
// ...
}
public void Deserialize(byte[] data)
{
// ...
}
}
Essentially, the intended code generator should find all user-defined types, any constraints, etc .. Is there some simple example?
If you want to look at an opensource data interchange system with roughly the characteristics you are proposing (multi-platform, multi-language, data definition language), you could do worse than looking at Google's Protocol Buffers, more commonly known as protobuf.
The data description language's compiler is not, unfortunately, generated from a grammar; but it is a relatively readable recursive-descent parser written in C++. Code generators for several languages are included, and many more are available.
An interesting feature is the interchange format can be described in itself. In addition, it is possible to code and decode data based on the description of the interchange format, so it is also possible to interchange format descriptions and use them ad hoc without the need of code generation. (This is less efficient, obviously, but is nonetheless often useful.)
Always a good starting point is the example grammars in the Antl4 repo. Simple grammars, like abnf, json, and less, might provide relevant starting points for your specification grammar. More complex grammars, like the several sql grammars, can give insights into how to handle more difficult or involved specification constructs -- each line of your specification appears broadly analogous to an sql statement.
Of course, Antlr 4 -- both its grammar and implementation -- is the most spot on example of reading a specification and generating a derived source output.
I have a requirement where i need to transfer information through the wire(binary over tcp) between 2 applications. One is in Java and the other in C++. I need a protocol implementation to transfer objects between these 2 applications. The Object classes are present in both the applications (are mapped accordingly). I just need some encoding scheme on one side which retains the Object representation on one side and can be decoded on the other side as a complete Object.
For eg,
C++ class
class Person
{
int age;
string name;
};
Java class
class Person
{
int age;
String name;
}
C++ encoding
Person p;
p.age = 20;
p.name = "somename";
char[] arr = SomeProtocolEncoder.encode(p);
socket.send(arr);
Java decoding
byte[] arr = socket.read();
SomeProtocolIntermediateObject object = SomeProtocolDecoder.decode(arr);
Person p = (Person)ReflectionUtil.get(object);
The protocol should provide some intermediate object which maintains the object representational state so that using reflection i can get back the object later.
Sounds like you want Protobufs: http://code.google.com/apis/protocolbuffers/docs/tutorials.html
Check out Google's protocol buffers.
Thrift is what you're looking for. You just create a definition of the structs and methods you need to call and it does all of the heavy lifting. It's got binary protocols (optionally with zlib compression or ssl). It'll probably do your taxes but you didn't hear that from me.
You might want to check out these projects and choose one:
Protocol Buffers
Thrift
Apache Avro
Here is a Thrift-vs-PB comparison I read recently. You should also refer to this Wiki for performance comparisons between these libraries.
You can check the amef protocol, an example of C++ encoding in amef would be like,
//Create a new AMEF object
AMEFObject *object = new AMEFObject();
//Add a child string object
object->addPacket("This is the Automated Message Exchange Format Object property!!","adasd");
//Add a child integer object
object->addPacket(21213);
//Add a child boolean object
object->addPacket(true);
AMEFObject *object2 = new AMEFObject();
string j = "This is the property of a nested Automated Message Exchange Format Object";
object2->addPacket(j);
object2->addPacket(134123);
object2->addPacket(false);
//Add a child character object
object2->addPacket('d');
//Add a child AMEF Object
object->addPacket(object2);
//Encode the AMEF obejct
string str = new AMEFEncoder()->encode(object,false);
Decoding in java would be like,
byte arr = amef encoded byte array value;
AMEFDecoder decoder = new AMEFDecoder()
AMEFObject object1 = AMEFDecoder.decode(arr,true);
The Protocol implementation has codecs for both C++ and Java, the interesting part is it can retain object class representation in the form of name value pairs,
I required a similar protocol in my last project, when i incidentally stumbled upon this protocol, i had actually modified the base library according to my requirements. Hope this helps you.
What about plain old ASN.1?
It would have the advantage of being really backed by a standard (and widely used). The problem is finding a compiler/runtime for each language.
This project is the ultimate comparison of Java serialization protocols:
https://github.com/eishay/jvm-serializers/wiki
Some libraries also provide C++ serialization.
I've personally ported Python Construct to Java. If there's some interest I'll be happy to start a conversion project to C++ and/or JavaScript!
http://construct.wikispaces.com/
https://github.com/ZiglioNZ/construct
In Google's Protocol Buffer API for Java, they use these nice Builders that create an object (see here):
Person john =
Person.newBuilder()
.setId(1234)
.setName("John Doe")
.setEmail("jdoe#example.com")
.addPhone(
Person.PhoneNumber.newBuilder()
.setNumber("555-4321")
.setType(Person.PhoneType.HOME))
.build();
But the corresponding C++ API does not use such Builders (see here)
The C++ and the Java API are supposed to be doing the same thing, so I'm wondering why they didn't use builders in C++ as well. Are there language reasons behind that, i.e. it's not idiomatic or it's frowned upon in C++? Or probably just the personal preference of the person who wrote the C++ version of Protocol Buffers?
The proper way to implement something like that in C++ would use setters that return a reference to *this.
class Person {
std::string name;
public:
Person &setName(string const &s) { name = s; return *this; }
Person &addPhone(PhoneNumber const &n);
};
The class could be used like this, assuming similarly defined PhoneNumber:
Person p = Person()
.setName("foo")
.addPhone(PhoneNumber()
.setNumber("123-4567"));
If a separate builder class is wanted, then that can be done too. Such builders should be allocated
in stack, of course.
I would go with the "not idiomatic", although I have seen examples of such fluent-interface styles in C++ code.
It may be because there are a number of ways to tackle the same underlying problem. Usually, the problem being solved here is that of named arguments (or rather their lack of). An arguably more C++-like solution to this problem might be Boost's Parameter library.
The difference is partially idiomatic, but is also the result of the C++ library being more heavily optimized.
One thing you failed to note in your question is that the Java classes emitted by protoc are immutable and thus must have constructors with (potentially) very long argument lists and no setter methods. The immutable pattern is used commonly in Java to avoid complexity related to multi-threading (at the expense of performance) and the builder pattern is used to avoid the pain of squinting at large constructor invocations and needing to have all the values available at the same point in the code.
The C++ classes emitted by protoc are not immutable and are designed so that the objects can be reused over multiple message receptions (see the "Optimization Tips" section on the C++ Basics Page); they are thus harder and more dangerous to use, but more efficient.
It is certainly the case that the two implementations could have been written in the same style, but the developers seemed to feel that ease of use was more important for Java and performance was more important for C++, perhaps mirroring the usage patterns for these languages at Google.
Your claim that "the C++ and the Java API are supposed to be doing the same thing" is unfounded. They're not documented to do the same things. Each output language can create a different interpretation of the structure described in the .proto file. The advantage of that is that what you get in each language is idiomatic for that language. It minimizes the feeling that you're, say, "writing Java in C++." That would definitely be how I'd feel if there were a separate builder class for each message class.
For an integer field foo, the C++ output from protoc will include a method void set_foo(int32 value) in the class for the given message.
The Java output will instead generate two classes. One directly represents the message, but only has getters for the field. The other class is the builder class and only has setters for the field.
The Python output is different still. The class generated will include a field that you can manipulate directly. I expect the plug-ins for C, Haskell, and Ruby are also quite different. As long as they can all represent a structure that can be translated to equivalent bits on the wire, they're done their jobs. Remember these are "protocol buffers," not "API buffers."
The source for the C++ plug-in is provided with the protoc distribution. If you want to change the return type for the set_foo function, you're welcome to do so. I normally avoid responses that amount to, "It's open source, so anyone can modify it" because it's not usually helpful to recommend that someone learn an entirely new project well enough to make major changes just to solve a problem. However, I don't expect it would be very hard in this case. The hardest part would be finding the section of code that generates setters for fields. Once you find that, making the change you need will probably be straightforward. Change the return type, and add a return *this statement to the end of the generated code. You should then be able to write code in the style given in Hrnt's answer.
To follow up on my comment...
struct Person
{
int id;
std::string name;
struct Builder
{
int id;
std::string name;
Builder &setId(int id_)
{
id = id_;
return *this;
}
Builder &setName(std::string name_)
{
name = name_;
return *this;
}
};
static Builder build(/* insert mandatory values here */)
{
return Builder(/* and then use mandatory values here */)/* or here: .setId(val) */;
}
Person(const Builder &builder)
: id(builder.id), name(builder.name)
{
}
};
void Foo()
{
Person p = Person::build().setId(2).setName("Derek Jeter");
}
This ends up getting compiled into roughly the same assembler as the equivalent code:
struct Person
{
int id;
std::string name;
};
Person p;
p.id = 2;
p.name = "Derek Jeter";
In C++ you have to explicitly manage memory, which would probably make the idiom more painful to use - either build() has to call the destructor for the builder, or else you have to keep it around to delete it after constructing the Person object.
Either is a little scary to me.