Click here to Skip to main content
15,885,244 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I’m trying to pass a handle to a serial port class to a form that will configure the serial port.
I can pass a handle to the constructor and it works fine/as I expect inside the constructor but I need a local copy of the handle that points to the port I can use after the constructor is finished to change the parameters of the serial port.
I can declare a local serial port class var.
I can copy of the original serial port’s class data to that var.
But I want a handle to the original not a local copy of its data.
Here is a snippet of code that shows what I"m trying to do

public ref class Config_Serial_Port_Form : public System::Windows::Forms::Form
{
public:
Config_Serial_Port_Form(System::IO::Ports::SerialPort^% initport)
{
initport->BaudRate = 600; //this accesses the correct port the way I want
theport = initport; //this only copies all the original to the local object 
//I need "theport" to be a pointer to the original not a copy fo the original 
InitializeComponent();
//
//TODO: Add the constructor code here
//
} 
void domystuff(void) //all this stuff works but only on my local copy of "theport" I want to do this to the original object instead
{
port_stuff^ port_stuff_ptr;
port_stuff_ptr = gcnew port_stuff(); 
this->Baud_Rate_comboBox->Text = port_stuff_ptr->BaudRate_to_string(theport);
this->Parity_comboBox->Text = port_stuff_ptr->Parity_to_string(theport);
this->handshakingcomboBox->Text = port_stuff_ptr->Handshake_to_string(theport);
this->databitscomboBox->Text = port_stuff_ptr->DataBits_to_string(theport);
if (theport->IsOpen)
this->portselectcomboBox->Text = theport->PortName;
this->portselectcomboBox->Items->AddRange(theport->GetPortNames());
this->portselectcomboBox->Items->Add("COM4");
}
protected:
/// summary;
/// Clean up any resources being used.
/// /summary
~Config_Serial_Port_Form()
{
if (components)
{
delete components;
}
}
private: System::IO::Ports::SerialPort^ theport; /// this gives me a second object not a handle to the original. 


private: System::IO::Ports::SerialPort^% theport;//I tried this but it won't compile

private: System::IO::Ports::SerialPort^* theport;//I tried this too with no luck


How can I create a pointer to a handle?
Posted
Updated 28-Jan-11 14:45pm
v3

You are conceptually mixing up some things. A "^" syntax already means by reference.
Here is the illustration and the proof at the same time:

C++
public ref class Port {
public:
    Port(int initialBaudRate) : BaudRate(initialBaudRate) {}
    int BaudRate;
}; //class Port

public ref class PortUser {
public:
    void ChangeBaudRate(Port^ port, int newRate) {
        port->BaudRate = newRate;
    }
}; //class PortUser

int main(array<System::String ^> ^args)
{
    PortUser portUser;
    Port^ port = gcnew Port(2400);
    portUser.ChangeBaudRate(port, 9600);
    Console::WriteLine(L"New baud rate = {0}", port->BaudRate);
    return 0;
} //main


Output:

New baud rate = 9600


That is the proof. If the function ChangeBaudRate worked with the (stack) copy of the Port instance, you would get the old value of 2400.

(Sorry my sample violates good incapsulation/visibility coding styles and makes little practical sense; it does not matter for the purpose of the illustration of by-reference parameters.)

In most aspects .NET ref types instantiated with gcnew behave like old-style C++ pointers. The major difference is that such pointers are volatile (underlying physical address may change) and are subject to Garbage Collection. The uniqueness of C++ in a set of all .NET languages is the ability to use value semantic with reference types. Example: the use of the ref class PortUser in the function main.

The operator "%" works much like "address" (i.e. the analog of old "&" operator). In this way it help transition from value to reference semantics. Consider the variant:

C++
int main(array<System::String ^> ^args)
{
    PortUser portUser;
    Port port(2400);
    portUser.ChangeBoudRate(%port, 9600);
    Console::WriteLine(L"New boud rate = {0}", port.BoudRate);
    return 0;
} //main


Now we're using value semantics for port instance, but in a call to ChangeBoudRate it again behaves like a by-reference parameter. 9600 again, to everyone's satisfaction :).

Thank you.
—SA
 
Share this answer
 
v10
Comments
Sandeep Mewara 29-Jan-11 2:02am    
Great answer and explanation... surely 5++!
Espen Harlinn 29-Jan-11 3:39am    
Great answer SAKryukov, 5+
Sergey Alexandrovich Kryukov 30-Jan-11 14:25pm    
Sandeep, Espen, thanks you very much for reassurance.
I've only used C++/CLI more than a year ago, few days in total, already forgot the most of stuff.
--SA
Hi SA
You are correct of course.
It turns out I was fooling my self with the development environment.
I was changing the properties in my code expecting to see the changes the next time I ran the code.
When I didn't see the changes the next time around I somehow convinced my self that I was not passing by reference but only passing by by value becuase the origianl form that contained the was not changed when I reran the program.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900