I am trying to create a packet and attach a custom object. I read through the manual and tried following their suggestions but I am stuck.
According to the manual: Non-cObject data can be attached to messages by wrapping them into cObject, for example into cMsgPar which has been designed expressly for this purpose.
cMsgPar has the function: setObjectValue(), so I attempted to add the class via this code:
// b is a pointer to a custom object
auto packet = createPacket("Msg");
packet->addPar("data");
packet->par("data").setObjectValue(b);
but I get a 'no matching function for call' error for the setObject value function. I checked the function declaration, which is:
cMsgPar & setObjectValue (cOwnedObject *obj)
which brings me back to square one. Trying to convert my custom class into something acceptable by Omnet to send to other nodes in my network.
Any help would be appreciated.
The recommended way of carrying own classes (objects) via message in OMNeT++ is to add this to definition of a message. For example:
cplusplus {{
#include "MyClass.h" // assuming that MyClass is declared here
typedef MyClass *MyClassPtr;
}};
class noncobject MyClassPtr;
packet MyPacket {
int x;
MyClassPtr ptr;
}
Reference: OMNeT++ Simulation Manual - 6.6 Using C++ Types
this is how i do it as an easy solution. Omnet++ already gave alot of ways to do it.
msg->addPar("preamble");
msg->par("preamble").setLongValue(0b01010101010101);
send(msg,"phyout");
i hope it will helpout
Related
(This is the next iterative question so I can figure out how to use WRL, after this one was answered I believe correctly.)
So I'm trying to build up to being able to access Bluetooth LE devices through WinRT via WRL.
Continuing in the pattern of a Microsoft example (which is for the uri WinRT class), I am trying at this point just to get the class factory for the DeviceWatcher Class. ( Documentation for that class seems to be here ), this is my pared-down example code:
#include <roapi.h>
#include <combaseapi.h>
#include <iostream>
#include <windows.foundation.h>
#include <windows.foundation.collections.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <stdio.h>
#include <windows.devices.enumeration.h>
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Devices::Enumeration;
int dummy;
ComPtr<IUriRuntimeClassFactory> uriFactory;
ComPtr<IUriRuntimeClass> uri;
ComPtr<IDeviceWatcherRuntimeClassFactory> devWatcherFactory; //This line produces the only error, "IDeviceWatcherRuntimeClassFactory undefined"
//(When the line is omitted, the code compiles, links, and produces the smart pointer to a uri class)
HRESULT hr, hr2, hr3;
int main()
{
// Initialize the Windows Runtime.
RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
// Get the activation factory for the IUriRuntimeClass interface.
ComPtr<IUriRuntimeClassFactory> uriFactory;
HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriFactory);
// Create a string that represents a URI.
HString uriHString;
hr = uriHString.Set(L"http://www.microsoft.com");
// Create the IUriRuntimeClass object.
ComPtr<IUriRuntimeClass> uri;
hr2 = uriFactory->CreateUri(uriHString.Get(), &uri);
dummy = 1;
}
It is the MS example, up to the point of its uri WinRT class construction, and compiles and links and correctly constructs the uri class smart pointer when I leave out my added line that declares the ComPtr for IDeviceWatcherRuntimeClassFactory
The line is my attempt to just create a smart-pointer for the DeviceWatcher class factory, and it fails with identified "IDeviceWatcherRuntimeClassFactory undefined". (It also fails if I use small "d" as the second letter of the type argument.
In using "IDeviceWatcherRuntimeClassFactory", I'm trying to proceed by exact analogy to the MS example.
Besides the MS online documentation for the DeviceWatcher class (3), which doesn't seem to help me, I've also tried looking at what VS2022 solution explorer shows as the expansion of the header windows.devices.enumeration.h (which also does not seem to be telling me what name to use as far as I can figure out).
I've also tried using the VS2022 Object Browser, pointed to a custom component set of all .winmd files in C:\Windows\System32\WinMetaData, and again the information is not helping me, given my level of knowledge.
Can someone give me a sound method, for an arbitrary WinRT class, to figure out the type to use for the smart pointer to the class factory?
And, to save another iteration, once I can make a smart pointer to the factory, I will
need to make a smart pointer to the class itself (in my case, to DeviceWatcher). Can someone tell me what exact name to use for the ComPtr type?
Thanks.
I ran into a problem I don't understand in my c++ android ndk code. When using the camera there are a number of callbacks you give the camera2 api such as these defined in a ACameraCaptureSession_captureCallbacks structure. Today I was trying to put all my camera code into a class, but when it came time to assign the callback functions I couldn't figure out how to do it. Right now I still have the callback functions as just external functions outside of the class.
So for the class:
ACameraCaptureSession_captureCallbacks captureCallbacks;
DualCamera::DualCamera(){
captureCallbacks.context = this;
captureCallbacks.onCaptureCompleted = onCaptureCompleted;
}
Then for the function:
void onCaptureCompleted (
void* context, ACameraCaptureSession* session,
ACaptureRequest* request, const ACameraMetadata* result){
}
Defined like this it works fine, but if I try to bring onCaptureCompleted inside my class I can't figure out how to assign it to captureCallBacks.onCaptureCompleted. I tried this.onCaptureCompleted, &DualCamera::onCaptureCompleted, casting to void * and a few others but I'm stuck. What's the right way to do this?
Thank you
I have a question regarding ROS2 messages or possibly just standard C++, maybe one of you have tried something similar before, or can tell me that what I am trying to accomplish won't work.
What I'm trying to create is a library that I can use to quickly create a ROS2 Node, dynamically add publishers and/or subscribers, depending on the situation, before starting the node.
The problem I'm facing is that ROS2 uses message types like std_msgs::msg::String. Example source can be found on github.
The source uses the following code to create a subscriber:
subscription_ = this->create_subscription<std_msgs::msg::String>("topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1));
I would like to create a function that can create a subscriber using a given message type i.e.:
void createListener(std::string topicName, 'messagetype')
{
auto subscription_ = this->create_subscription<'messagetype'>(topicname, 10, [this]{}, this, _1));
//adding the created subscriber to a list is already done
}
This would allow me to use the same function while still being able to use different messages like:
nav_msgs::msg::Path
geometry_msgs::msg::Point
without having to create a new function for every message type.
I can't seem to find the template type that is used in the create_subscribtion<>() function, all I can find is that each message creates its own type.
std_msgs::msg::String would return the std_msgs::msg::String_<std::allocator<void>> type.
Is there a way that i can make this work?
You could use templates here right, by doing the following:
template <typename MsgType>
void createListener(std::string topicName)
{
auto subscription_ = this->create_subscription<MsgType>(topicname, 10, [this]{}, this, _1));
//adding the created subscriber to a list is already done
}
This function can then be called, for example by:
createListener<nav_msgs::msg::Path>("topicName")
I'm trying to get my feet wet with ASIO and thought a good first project would be a simple web crawler: download an html page, find the links in it, download all the links.
I have tried modifying the ASIO http client example to use enable_shared_from_this instead of a raw pointer so that I can spawn new async task from within the handler of the previous task without having to worry about the resources getting deleted in the middle of my work.
The problems start when I tried to subclass my client to handle different pages in different ways. The compiler complains that the type of the shared_ptr doesn't match the type of this.
Does anybody know how this is solved? I haven't been able to figure it out by myself.
This is unrelated to Asio.
If you inherited a base class from enable_shared_from_this, but need it in the derived one, use boost::static_pointer_cast:
struct base : enable_shared_from_this<base>
{
};
struct derived : base
{
shared_ptr<derived> shared_from_derived()
{
return static_pointer_cast<derived>(shared_from_this());
}
};
I have a TcpDevice class which encapsulates a TCP connection, which has an onRemoteDisconnect method which gets called whenever the remote end hangs up. Then, there's a SessionManager object which creates TcpSession objects which take a TcpDevice as a communication channel and inserts them in an internal pointer container for the application to use. In case any of the managed TcpSessions should end, I would like the SessionManager instance to be notified about it and then remove the corresponding session from the container, freeing up the resources associated with it.
I found my problem to be very similar to this question:
Object delete itself from container
but since he has a thread for checking the connections state, it gets a little different from mine and the way I intended to solve it using boost::signals, so I decided to go for a new question geared towards it - I apologize if it's the wrong way to do it... I'm still getting the feel on how to properly use S.O. :)
Since I'm kind of familiar with QT signals/slots, I found boost::signals offers a similar mechanism (I'm already using boost::asio and have no QT in this project), so I decided to implement a remoteDeviceDisconnected signal to be emitted by TcpDevice's onRemoteDisconnect, and for which I would have a slot in SessionManager, which would then delete the disconnected session and device from the container.
To initially try it out I declared the signal as a public member of TcpDevice in tcpdevice.hpp:
class TcpDevice
{
(...)
public:
boost::signal <void ()> remoteDeviceDisconnected;
(...)
}
Then I emitted it from TcpDevice's onRemoteDisconnect method like this:
remoteDeviceDisconnected();
Now, is there any way to connect this signal to my SessionManager slot from inside session manager? I tried this:
unsigned int SessionManager::createSession(TcpDevice* device)
{
unsigned int session_id = session_counter++;
boost::mutex::scoped_lock lock(sessions_mutex);
sessions.push_back(new TcpSession(device, session_id));
device->remoteDeviceDisconnected.connect(boost::bind(&SessionManager::removeDeadSessionSlot, this));
return session_id;
}
It compiles fine but at link time it complains of multiple definitions of remoteDeviceDisconnected in several object code files:
tcpsession.cpp.o:(.bss+0x0): multiple definition of `remoteDeviceDisconnected'
tcpdevice.cpp.o: (.bss+0x0): first defined here
sessionmanager.cpp.o:(.bss+0x0): multiple definition of `remoteDeviceDisconnected'
tcpdevice.cpp.o: (.bss+0x0): first defined here
I found this strange, since I didn't redefine the signal anywhere, but just used it at the createSession method above.
Any tips would be greatly appreciated! Thank you!
My bad! Like we all should expect, the linker was right... there was indeed a second definition, I just couldn't spot it right away because it wasn't defined by any of my classes, but just "floating" around one of my .cpp files, like those found on boost::signals examples.
Just for the record, the initial idea worked like a charm: when a given TcpDevice gets disconnected from the remote end, it emits the remoteDeviceDisconnected signal, which is then caught by the SessionManager object which holds the TcpSession instance that points to that TcpDevice. Once notified, SessionManager's method removeDeadSessionSlot gets executed, iterating through the sessions ptr_list container and removing the one which was disconnected:
void SessionManager::removeDeadSessionSlot()
{
boost::mutex::scoped_lock lock(sessions_mutex);
TcpSession_ptr_list_it it = sessions.begin();
while (it != sessions.end()) {
if (!(*it).device->isConnected())
it = sessions.erase(it);
else
++it;
}
}
Hope that may serve as a reference to somebody!