I'd like to do some message debugging on traffic for a few protobuf based services we use.
The services all use compiled .proto files for messages, and I'd like to serialize the actual format of the message back to .proto file text and send that to a client so that the client does not need to know implementation details at compile time.
Is this possible in C++? I know that I can get the structure of a message without the definition, but having the names of the message fields would be critical for debugging. Is there another way of getting this information without having the .proto files?
Thanks!
If the original sender has the .proto files, they can be compiled by "protoc" into a protobuf data file, matching "descriptor.proto" (which should be available in your distribution of protobuf). You can do this by using
protoc --descriptor_set_out={out_path} --proto_path={in_path}
(or to stdout if you prefer, IIRC - untested)
The resultant binary data can be included as a bytes field, and deserialized serparately as long as the client also has an object-model generated from descriptor.proto.
In terms of what to do once you have deserialized it: FileDescriptorSet is the top-level object; you should be able to traverse down to FieldDescriptorProto, which has the member-name etc
Perhaps not very elegant, but it should work.
Alternatively, include the metadata any-which-way, and treat everything as extension fields.
Related
I'm new in Mavlink, I want to add a new message in the Mavlink protocol and send it each second periodically. How can I do it?
Here you can find detailed steps about how to add new message to mavlink protocol and how you handle it.
Ensure you have the latest ArduPilot code and Mavproxy installed.
Decide what type of message you want to add.
Add the new message definition to the common.xml or ardupilotmega.xml file in the mavlink submodule.
Add functions to the main vehicle code to handle sending or receiving the command.
It depends on what autopilot you are using. If you're using ardupilot then you would need to add a new xml message definition in ardupilot/modules/mavlink/message_definitions/v1.0/ardupilotmega.xml.
You can look at the other messages to see how it should be formatted. Just make sure you choose an id that is unused.
Next you need to decide how to put this in the code. You could place it in the data_stream_send task by adding the message id to, say, STREAM_EXTRA3. This will send your message as often as the other data is sent there. As part of that you will need to define the function to actually pack your data structure using the function generated by pymavgen, the message id and enumerations. This is what I have done in my own project for ASH_DATA. You can see the changes I've made in my repository for reference. Note that some of those include changes to incorporate reception of ash data on the pixhawk and adding the data to a log file.
Given that you want to run this once a second you may want to add to the one_second_loop task or create your own task that simply calls the try_send_message function using your new message id.
You will of course need to incorporate the new message in your gcs so you can actually receive it, but that's another matter.
Hopefully this can nudge others in the right direction who are trying to do the same.
What is the best practice of logging DLL activity and internal parameter values.
I wrote a DLL that is used by a few applications I wrote. Lately, some users were complaining about problems that I suspect are related to this DLL but I cannot reproduce on my dev machine.
I'd like send them an equivalent DLL file that will log its activity, such as function calls, function return values and some internal parameters.
I don't think there should be a problem for a DLL to create a log file and write to it. Is there a common practice related to this issue. Is there a standard place to write the data to?
I am currently facing a similar issue of how to provide logging from a DLL. The way I went about it is to provide callback function setters and a callback type header file as part of the API. That way, the caller of the dll can create their own type of logging (boost, log4cpp, etc) and the dll will call the callback function in the exe that the user can do whatever they want with the data. In my case, I forward the log msgs to a boost logger that is instantiated in the exe. It's a little hacky looking but seems to work pretty well since the exe controls when and how to log everything and the user can format the data any way they choose.
You could provide an interface on your DLL which allows the user to provide a log file path/handle as the logging sink.
If you auto-generate the log file you'll probably want the file name to contain the process name and the process id (to disambiguate multiple simultaneous runs).
on unix machines the usual place is /var/log
on windows the standard way is to log to the event log (a separate subsystem of the OS).
I would suggest using the active user's TEMP directory if you want to log to file...
...or you could be clever and get the DLL to log to your own machines via TCP.
say I want to format my fix message received in a XML form ( not FIXML ! ) but kind of like the spec description, for example like that
<message name="Heartbeat" msgcat="admin" msgtype="0">
<field name="TestReqID" required="N" />
</message>
and in my output I need to have a c++ struct or a class called HeartbeatMsg whose attribute are its own fields.
So after parsing my XML file, I want to stock those messages parsed into an object that I can call later by a printer or formatting class that take my message object and write it into a file.
so I thought this message object that I want to instantiate maybe I can create it as a new class that inherit from the message class in the QuickFix library, so my question is :
could I do it? because I read the QuickFix message and it's loaded with functions that can be used for more than describing the message but also for extracting it, serializing it
from a stream input.
so although my need is far away from that, can I still use this classe for a simple formatting.
What you get from your XML can be parsed into a FIX object, using the Quickfix library. But it is going to be doing the work twice. 2 places when it can be done
When you receive and process your XML message to use, you can as a concurrent job create a FIX message using the Quickfix library. But that would surely slow down the processing of your original application.
When you process the XML message and convert it into a format your code understands, store that object you create and create a FIX message out of it as a side task totally independent of your original application. That way your original application runs as it is and it doesn't care about the FIX message creation. But you may have to copy your objects to a place from where the FIX message creation can be started.
Both require a combination of your original API and Quickfix library. So be careful when integrating them.
I have a VS2010 project which is a windows application that acquires data from a particular bluetooth device. All I want to do is alter my acquisition thread to send the data it acquires using OSC.
I spent a long time trying to use a library called LIBLO but it appears to function using POSIX style asynchronicity. I spent even more time trying to make pthreads-win32 work for me so that I could still use this library but still had no luck.
I switched to trying to use the OSCPACK library which I could not get to compile using the batch file included in the release. I was eventually able to get my VS2010 project to recognise the library but all I get now are linker errors (LNK2019 and LNK2001). The relevant directories are listed in "Additional Include Directories" in the project properties. I know this should be something easy to fix but after a day of frustration I am at my wits' end. I am used to working with xcode in osx so find it difficult to accomplish anything in VS2010. Do I need to give additional instructions to the linker?
can anyone either suggest a simple, prebuilt OSC library compatible with windows/VS or how I can fix my problem with unresolved externals?
OSC is a very simple protocol, especially if you only need to send outgoing OSC messages and don't care about receiving (and parsing) incoming OSC messages. One thing you can do is simply read the spec and look at some examples and write your own function that adds OSC data into a byte buffer in the prescribed format. That's only a few hours of work to do. Then it's just a matter of sending that char buffer out over a UDP socket, which is also quite straightforward to do. Depending on your needs, that might be easier that trying to integrate with a third-party OSC library (which I agree can be frustrating, especially under Windows).
Another possibility is to use OSCPACK, but instead of trying to build it separately and then link to the resulting DLL/LIB file, simply copy the necessary OSCPACK .c files directly into your own project's source tree and compile them in to your executable the same way you compile your own code. That will avoid any annoying build/link issues that can come with trying to get two different build systems to work together, and it also gives you full control over your (bastard) copy of the OSC code... e.g. if you want a particular function in OSCPACK to work differently, you can simply modify your copy of that function. (If you do that, be sure to make it obvious that the code is no longer 'stock', to avoid confusion... and of course try not to modify it in such a way as to break protocol compatibility with other OSC-using software)
I try to send integer value from one to another programme using for IPC QtDBUS(they are different executable files). My attempts to find simple example was unsuccessful. So, I am forced to build huge example D-Bus Remote Controlled Car Example like for one who has never used QtDBus. I repeated full tree structure(sources, headers). But one file controller.h includes #include “ui_controller.h”. There is no such file. So, I am not able to compile.
Maybe, is there something that I don’t understand?
http://s016.radikal.ru/i336/1112/ad/d4f681cbc2cd.png
Yes, ui_* files are generated in the build process. You can find the complete sources of all the dbus examples, including the one you're referring to here.