Subcriber problem in visual studio C++ windows forms
Rosserial Windows worked well when I used Visual Studio as described in link text for Win32 Console Application.
But when I used Windows Forms Application (File->New->Project & select Visual C++ -> Windows Forms Application), it has a problem. I created a simple windows forms program with button1, listbox1 and a timer1. All the steps are the same as for Win32 Console Application. The code for the program and for button1_Click(...) and timer1_Tick(...) are given below. With $roslaunch rosserial_server socket.launch and $rosrun beginner_tutorials talker running on linux machine (IP address:192.168.186.132) and with this windows forms running on Windows.... and when button1 is clicked, it worked fine (if timer1 was disabled) with message
Connecting to server at 192.168.186.132 Message Received: Hello World 9
But when I enabled timer1->Enabled = true (uncomment it) in the button1_Click (...) function below to allow timer1 to execute automatically every 100 ms and run the spinOnce() function. I encountered windows problem with error message: "An unhandled exception of type 'System.NullReferenceException' occurred in Test Rosserial windows forms.exe. Additional information: Object reference not set to an instance of an object." The error pointed at line subscribers[topic_-100]->callback( message_in ); in Virtual Int spinOnce () function in node_handle.h.
I have spent quite a lot of time debugging but still could not solve the problem. Does anyone know where the problem is? You can use the code below and try.
Really appreciate your help.
#pragma once
#include <string.h>
#include <stdio.h>
#include <ros.h>
#include <std_msgs/String.h>
#include <windows.h>
using std::string;
ros::NodeHandle nh;
char *ros_master = "192.168.186.132";
std_msgs::String chatter_msg;
string test_str;
bool callback_done = false;
void chatterCallback(const std_msgs::String &chatter_msg)
{
test_str = chatter_msg.data;
callback_done = true;
}
namespace TestRosserialwindowsforms {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected: . . .
private:
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
String^ message;
// Connecting to server and init ROS node
message = gcnew String(reinterpret_cast<const char*>(ros_master));
message = "Connecting to server at " + message;
listBox1->Items->Add (message);
nh.initNode (ros_master);
ros::Subscriber <std_msgs::String> chatter_sub ("chatter", &chatterCallback);
nh.subscribe (chatter_sub);
while (callback_done !=true)
{
nh.spinOnce ();
Sleep (100);
}
listBox1->Items->Add("Message received: ");
String^ str2 = gcnew String(test_str.c_str());
listBox1->Items->Add (str2);
//timer1->Enabled=true;
}
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
nh.spinOnce ();
if (callback_done)
{
callback_done = false;
String^ str2 = gcnew String(test_str.c_str());
listBox1->Items->Add (str2);
}
}
};
}