How to get c++ class to communicate with Windows Form textbox - forms

I am currently writing a program in C++/CLI. I have a Windows Form which acts as a user interface. Now what I want to do is to declare a separate c++ class and give it access to a textbox on the form.
The form is declared in the file MyForm.h
The class is defined by a header file and cpp file, lets call them myClass.cpp and myClass.h
The functionality of the program should be as follows : The program should go through all the serial ports that are currently available, then try to open them and poll them for data. If there is a good answer from the serial port then then it should end searching and keep connected to this port. So in this case myClass should check for serial ports and return the name of the desired port. I also want to be able to track the progress of the port searching thread in a textbox on the windows form. I could probably just include the port search into the initialization code of the form, but that would be really messy and would result in a large chunk of code in a single header file. This does not really seem reasonable.
I know that I cannot directly access the Windows form textbox and have to use an Invoke method, this is currently not the problem. The problem is that I really do not know how to get the two classes to communicate with each other. I have tried declaring a pointer to a MyForm object, but this does not seem to be working. I cannot seem to get header and cpp files to connect.
I'm sorry if this sounds confusing, I'll try to explain by example and also code.
Just for concept testing I made a really simple program that consists of a Windows Form and a class called simpleAdder.
//simpleAdder.h
#pragma once
#include "MyForm.h"
using namespace System;
using namespace simpleClassTest;
public ref class simpleAdder
{
private:
Int16 a;
Int16 b;
MyForm^ m_form;
public:
simpleAdder(Int16 x,Int16 y, MyForm^ form);
Int16 add (void);
};
Here is the cpp file for simpleAdder :
//simpleAdder.cpp
#include "MyForm.h"
#include "simpleAdder.h"
using namespace System;
using namespace simpleClassTest;
simpleAdder::simpleAdder(Int16 x,Int16 y, MyForm^ form){
a = x;
b = y;
m_form = form;
}
Int16 simpleAdder::add (void){
return a+b;
//Try to invoke the textbox method. This is not implemented yet.
}
So the idea is that I would have a managed pointer to an existing form and through this, I could access the form itself. The adder class should basically just try to write the result of the x+y onto the form textbox.
Here is some code from the MyForm.h file
#pragma once
#include "simpleAdder.h"
namespace simpleClassTest {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
//ref class simpleAdder;
/// <summary>
/// Summary for MyForm
/// </summary>
public ref class MyForm : public System::Windows::Forms::Form
{
public:
MyForm(void)
{
InitializeComponent();
this->m_add = (gcnew simpleAdder (16,10));
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~MyForm()
{
if (components)
{
delete components;
}
}
private:
/// <summary>
/// Required designer variable.
/// </summary>
simpleAdder^ m_add;
private: System::Windows::Forms::Button^ button1;
private: System::Windows::Forms::TextBox^ textBox1;
System::ComponentModel::Container ^components;
//Here follows the automatically generated code.
The problem is that no matter what I do, I cannot get this to compile. The compiler does not recognize the MyForm type variable. Also having two headers that include each other does not seem right, but I really don't know what else to do. I tried declaring both classes in the same namespace, but that did not help either. Then I tried forward declaring the simpleAdder class in the MyForm header file, but that did not work.
I am obviously not experienced in c++/cli and it seems that I am doing something fundamentally wrong. I think there must be a better way to implement something like this. I mean in the end I would have to add other classes to the windows form to display information etc. There must be an easy way of doing this. Any help on this would be much appreciated.

Lets look at order of includes:
simpleAdder.cpp include MyForm.h
MyForm.h include simpleAdder.h
Inside simpleAdder.h include to MyFrom.h is skipped becose #pragma once
Then there is code:
public ref class simpleAdder
{
private:
Int16 a;
Int16 b;
MyForm^ m_form;
public:
simpleAdder(Int16 x,Int16 y, MyForm^ form);
Int16 add (void);
};
but there wasn't MyForm declared anywhere.
Read about forward declaration. You can declare MyForm before simpleAdder:
public ref class simpleAdder; // or without public

Related

Converting UML to code c++. Problem with inheritence. Do constructors of all classes run when object of any one of them is created?

I have this UML diagram
Ad this is the corresponding C++ code
//Parent class Flight
class Flight
{
private:
int callNumber;
Airplane plane;
vector<Passenger> passengers;
public:
//Constructor
Flight();
//Functions
int getCallNum();
void setCallNum();
Airplane getPlane();
//What parameters are taken in these functions.
//I know they are of type Airplane and passenger but are they vectors?
void setPlane(Airplane);
void addPassenger(Passenger);
void removePassenger(Passenger);
};
//Airplane class, child of Flight
class Airplane : public Flight
{
private:
int firstClassSeats;
int economySeats;
public:
//Constructor
Airplane();
//Functions;
int getFirstClassSeats();
int getEconomySeats();
void setFirstClassSeats();
void setEconomySeats();
};
//Passenger class, child of FLight
class Passenger : public Flight
{
private:
string name;
int age;
string address;
public:
//Constructor
Passenger();
//Functions
string getName();
int getAge();
string getAddress();
void setName(string);
void setAge(int);
void setAddress(string);
};
I wonder:
do constructors of all classes run when an object of either parent or base class is created?
Can base class access functions or data of child classes?
I do not know how set plane function in parent class would look like. Would it take an object of type Airplane as an argument? Similarly, will addpassenger function in parent class take a vector of type Passenger as an argument?
In short
If A inherits B (or A specializes B), then you should be able to say A is a (kind of) B. When in doubt, prefer object composition over inheritance.
More details
The parameters taken by the member functions, are the parameters that you indicate for the operations in the diagram. No parameter in the diagram leads to no parameters in the code.
The inheritance here is ambigous. There is no inheritance in your diagram. There is some in your code, but it does not make so much sense: is a passenger really a flight? E.g. can a passenger fly, have a crew, etc.?
If the inheritance would be suitable, as a general rule in C++: the constructor of an object is always called when the object is created. In case of inheritance, all the constructors of the class hierarchy are invoked, starting with the base constructor, until the most derived constructor (the rules can be more tricky, for example in case of multiple inheritance). In UML, the rules on constructors are not fully specified as far as I know.
By default, a class can only access public members of another class. If a class is derived from a base class (in UML: if a class is a specialisation of a more general class), the derived class has only access to the public and protected members of the base class. Try to avoid protected, since it's a frequent cause of nasty bugs.
WHen implementing in C++ an UML class diagram, there is a tricky issue about the types of the properties and arguments, because C++ has a value semantic: if you pass an Airplane as argument, the original airplane object is copied. Same if you have an Airplane property. However, in UML, properties and associations have a reference semantic (except for datatypes), meaning that the airplane argument would still refer to the same original airplane. So in your specific case, you'd probably want to pass a reference or a (smart) pointer to an Airplane.

Can I define a reusable subroutine/function/method within a Cake script?

I'm trying out Cake (C# Make). So far all the examples and documentation have the script file declaring all of its code inside delegates, like this:
Task("Clean")
.Does(() =>
{
// Delete a file.
DeleteFile("./file.txt");
// Clean a directory.
CleanDirectory("./temp");
});
However, one of the reasons I'm interested in using Cake is the possibility of writing my build scripts in a similar way to how I write code, as the scripts use a C#-based DSL. Included in this possibility is the ability to separate code that I use into methods (or functions / subroutines, whatever terminology is appropriate) so I can separate concerns and reuse code. For example, I may want to run the same set of steps for a multiple SKUs.
While I realize that I could create my own separate DLL with Script Aliases, I would like to avoid having to recompile a separate project every time I want to change these bits of shared code when working on the build script. Is there a way to define, inline with the normal build.cake file, methods that can still run the Cake aliases (e.g., DeleteFile) and can themselves be called from my Cake tasks?
Cake is C#, so you can create classes, methods, just like in regular C#
I.e. declare a class in a cake file
public class MyClass
{
public void MyMethod()
{
}
public static void MyStaticMethod()
{
}
}
and then use it a script like
var myClass = new MyClass();
// Call instance method
myClass.MyMethod();
//Call static method
MyClass.MyStaticMethod();
The Cake DSL is based on Roslyn scripting so there are some differences, code is essentially already in a type so you can declare a method without a class for reuse
public void MyMethod()
{
}
and then it can be called like a global methods
MyMethod();
A few gotchas, doing class will change scoping so you won't have access to aliases / context and global methods. You can get around this by i.e. passing ICakeContext as a parameter to class
public class MyClass
{
ICakeContext Context { get; }
public MyClass(ICakeContext context)
{
Context = context;
}
public void MyMethod()
{
Context.Information("Hello");
}
}
then used like this
// pass reference to Cake context
var myClass = new MyClass(Context);
// Call instance method which uses an Cake alias.
myClass.MyMethod();
You can have extension methods, but these can't be in a class, example:
public static void MyMethod(this ICakeContext context, string message)
{
context.Information(message);
}
Context.MyMethod("Hello");

How to use a C++ class with pure virtual function?

I was given a class with pure virtual function like the following:
class IRecordingHour{
public:
virtual int getData() const = 0;
}
Now, I have another class that uses the IRecordingHour class:
class ProcessRecordingHours {
public:
ProcessRecordingHours (IRecordingHour &);
proteted:
IRecordingHour & recordingHour;
}
I was told that I am not allowed to implement the IRecordingHour class (the one with the pure virtual function).
My question is: without implementing the IRecordingHour clas, how do I use it in the ProcessingRecordingHours? That is, how do I create an instance of the IRecordingHour and pass it to the constructor of the ProcessRecordingHours?
You should create a subclass of IRecordingHour and implement the method getData, like
class ARecordingHour : public IRecordingHour
{
public:
int getData() const override //override is valid from C++11
{
return 42;
}
}
And then you can do:
ARecordingHour arh{};
ProcessRecordingHours prh{arh}; //{}- Modern C++ initialization
You can find similar examples in a good C++ programming book, such as The C++ Programming Language
Though you equate them, your two questions are in fact quite different.
how do I use it in the ProcessingRecordingHours?
There is no particular problem in implementing ProcessingRecordingHours without implementing a subclass of IRecordingHour. You don't need to do anything special. You simply avoid relying on anything not declared by IRecordingHour, which is no different than you ought to do anyway.
how do I create an instance of the IRecordingHour and pass it to the constructor of the ProcessRecordingHours?
You cannot. A class with a pure virtual method cannot be directly instantiated. Your ProcessRecordingHours can be used in conjunction with classes that extend IRecordingHour, but if you are not permitted to create such a class then you cannot exercise those parts of your ProcessRecordingHours class that depend on an IRecordingHour.
Perhaps, however, you have misunderstood the problem. You may be forbidden from implementing IRecordingHour::getData(), but not from implementing a subclass that overrides that method with a concrete one. Such a subclass could be instantiable, and would be usable in conjunction with ProcessRecordingHours.
I think your teacher plan to inject an implementation of IRecordingHour into ProcessRecordingHours.
Also, you can't use that class unless you generate a stub for IRecordingHour or you implement one yourself with some dummy return values.
/// <summary>
/// in C# and interface can only contain virtual methods. so no need to say virtual.
/// </summary>
interface IRecordingHour
{
int getData();
}
class MockRecordingHour : IRecordingHour
{
public int getData()
{
//just return something. This will be enough to get ProcessRecordingHours to work
return 100;
}
}
/// <summary>
/// this class expects a IRecordingHour.
///
/// how we get a IRecordingHour depends on who's implementing it. You, some 3rd party vendor or another developer who's using this class that you've written.
///
/// Oh wait. Since you're building ProcessRecordingHours, you need a IRecordingHour to get against. You can use a mocking tool or create one yourself that returns some dummy data
/// </summary>
class ProcessRecordingHours
{
private IRecordingHour _recording;
public ProcessRecordingHours(IRecordingHour recording)
{
this._recording = recording;
}
public void DoSomething() {
Console.WriteLine("Recording Data: {0}", this._recording.getData());
}
}

Class from Interface.cll

I'm trying to implement a class instance of an interface class. Exploring the interface (.NET DLL) with the project explorer, it says:
bool CreateInstance(SharedLibrary::MemoryArbiter^ pntMemory,
SharedLibrary::clsMessageQueue^ pntMessageQueue,
SharedLibrary::clsGPIO^ pntGPIO,
SharedLibrary::Types^ pntProgramSettings,
SharedLibrary::DisplayDriver^ pntDisplayDriver)
Member from Plugin_Interface::IPlugin
But if I write in my MyClass.h:
using namespace System;
using namespace System::ComponentModel;
using namespace SharedLibrary;
namespace MyCppPlugin {
[AttributeUsageAttribute(AttributeTargets::Class | AttributeTargets::Method |
AttributeTargets::Property | AttributeTargets::Field,
AllowMultiple = true, Inherited = false)]
ref class MyPlugin abstract : public Plugin_Interface::IPlugin
{
bool CreateInstance(SharedLibrary::MemoryArbiter^ pntMemory,
SharedLibrary::clsMessageQueue^ pntMessageQueue,
SharedLibrary::clsGPIO^ pntGPIO, SharedLibrary::Types^
pntProgramSettings, SharedLibrary::DisplayDriver^ pntDisplayDriver);
};
};
It says: "error C3766: Missing implementation of Plugin_Interface::IPlugin::CreateInstace(...)
What the heck do I do wrong?
EDIT:
Forgot the abstract statement.
And: Why is it saying "IntelliSense: Class can not implement interface member function "Plugin_Interface::IPlugin::CreateInstance" (declared in "Plugin_Interface.dll")"
???
You got a lot more diagnostic messages from this snippet, you are making several mistakes:
[AttributeUsage] is only valid on a class that derives from System::Attribute. You no doubt need to use some kind of attribute so that the plugin host can recognize your class as a valid plugin candidate, I can't guess what that attribute might be.
A method that implements an interface method should be public.
A method that implements an interface method must be virtual.
The method signature must be an exact match with the interface method declaration.
Just in case: you must actually implement the method, not just declare it.
The third and forth bullets are the chief reasons for the "must provide an implementation of the interface method" compile error. So proper code ought to resemble something like this:
[NoIdeaWhatAttribute]
public ref class MyPlugin : public Plugin_Interface::IPlugin {
public:
virtual bool CreateInstance(SharedLibrary::MemoryArbiter^% pntMemory,
SharedLibrary::clsMessageQueue^% pntMessageQueue,
SharedLibrary::clsGPIO^% pntGPIO,
SharedLibrary::Types^% pntProgramSettings,
SharedLibrary::DisplayDriver^% pntDisplayDriver)
{
// Todo...
return false;
}
};
I got it. Thanks to Hans Passant who gave me so many hints :)
To export the function it has to implement the Interface 1:1. The export statement has to be added over the class header:
[Export(IPlugin::typeid)]
public ref class MyPlugin : public Plugin_Interface::IPlugin
And: While VB.NET will compile to "Any CPU" and C++/CLI will compile to Win64/Win32 it will missfit. Both Projects have to have the same target - either 64bit OR 32bit.
Now it works.

extending protected functions boost::python

I have C++ code (not mine, so it is not editable). Problem is with extending protected functions and class.
#include "ExtraClass.h"
...
MyClass::MyClass()
{
...
protected:
bool Func{}
ExtraClass m_Foo;
...
}
I need access in Python to m_Foo methods and protected functions like Func() like
from MyClass import *
bar = MyClass()
bar.m_Foo.Run() //something like this
but have an compiler error:
*error: ‘ExtraClass MyApp::m_Foo’ is protected*
PS. If I change protected with public (just for try). I can access *m_Foo* only in readonly mode:
class_<MyClass>("MyClass", init<>())
.def_readonly("m_Foo", &MyClass::m_Foo)
Changing to *def_readwrite* went to compiler error:
/boost_1_52_0/boost/python/data_members.hpp:64:11: error: no match for ‘operator=’ in ‘(((ExtraClass)c) + ((sizetype)((const boost::python::detail::member<ExtraClass, MyClass>*)this)->boost::python::detail::member<ExtraClass, MyClass>::m_which)) = d’
Thank you for any help!
In general, if you want to wrap protected members, then you need to derive a (wrapper) class from the parent that makes the members public. (You can simply say using Base::ProtectedMember in a public section to expose it instead of wrapping it). You will then have wrap it normally. Like this:
class MyWrapperClass : public MyClass {
public:
using MyClass::m_Foo;
};
In this particular example (which is really not fully baked), if you want to access m_Foo, then you need to wrap ExtraClass. Assuming that you have The problem with readwrite is likely the implementation of ExtraClass (which probably doesn't supply a operator= that you can use).