Sandra K Sandra K - 1 month ago 10
C# Question

Why do I have C# code in my C++ Windows Form and C++ functions are popping errors?

I have an assignment of building a simple calculator as a C++ Windows Form.

For now it is one TextBox and One button, sample input to the TextBox is

3 + 2
and the button should print their result on the same TextBox.

I created a New Project -> C++ Windows Form:

enter image description here

But some codes were generated automatically, which look like C# codes and I did not see before.

Original code after adding the Button and the TextBox:

#pragma once

namespace CppWinForm1 {

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;

/// <summary>
/// Summary for MyForm
/// </summary>
public ref class MyForm : public System::Windows::Forms::Form
{
public:
MyForm(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}

protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~MyForm()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
private: System::Windows::Forms::TextBox^ textBox1;
protected:

private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->button1 = (gcnew System::Windows::Forms::Button());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(59, 81);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 0;
this->button1->Text = L"button1";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &MyForm::button1_Click);
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(59, 31);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(100, 22);
this->textBox1->TabIndex = 1;
//
// MyForm
//
this->AutoScaleDimensions = System::Drawing::SizeF(8, 16);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(282, 253);
this->Controls->Add(this->textBox1);
this->Controls->Add(this->button1);
this->Name = L"MyForm";
this->Text = L"MyForm";
this->ResumeLayout(false);
this->PerformLayout();

}
#pragma endregion

}

};
}


And when I add my stuff in the above file (MyForm.h):

#include <string>
#include <msclr\marshal_cppstd.h> // for converting String^ to string

using namespace std;

// ..

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
System::String^ temp = textBox1->Text; // system string
std::string InputString = msclr::interop::marshal_as<std::string>(temp); // convert to standard string

int FirstNumber = 0,
SecondNumber = 0,
Result = 0,
MyInc = 1;
char MyOperator;

int SpaceIndex = InputString.find(' ');

for (int i = SpaceIndex - 1; i >= 0; i--)
{
FirstNumber += InputString[i].ToInt32() * MyInc;
MyInc *= 10;
}

MyOperator = InputString[SpaceIndex + 1];

InputString = InputString.substr(0, SpaceIndex + 2);

MyInc = 1;

for (int i = InputString.length() -1; i >= 0; i--)
{
FirstNumber += InputString[i].ToInt32() * MyInc;
MyInc *= 10;
}

if (MyOperator == '+')
Result = FirstNumber + SecondNumber;

textBox1->Text = Result.ToString();


I get this error on .ToInt32() function:


Too few arguments for the function call


Also in MyForm.Cpp (Which I did not touch) there is the same error:

#include "MyForm.h"

using namespace System;
using namespace System::Windows::Forms;

[STAThread]
void Main(array<String^>^ args) // Error here saying too few Arguments
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);

CppWinForm1::MyForm form;
Application::Run(%form);
}


Could someone point me on why this is happening? Please and Thanks

Answer

The generated code is C++/CLI, a superset of Standard C++. Note, that it's not C#. There are a number of differences, e.g. the namespace separator being :: vs ., or the ref class contextual keyword. C++/CLI compiles to MSIL (managed code), but can contain native C++, producing a so-called mixed-mode assembly. It's primarily used for managed/unmanaged interop.

The compiler error you receive for InputString[i].ToInt32() is a bit misleading. It's a result of the complexity of the language, the compiler trying all potential ways to interpret an expression, and when it finally gives up, the error it encountered is not always the most comprehensible one.

In this case, InputString[i] invokes std::string::operator[], which returns a reference to char. This is an integral data type in C++, not a class type with member methods. If you need to convert a string or character to an integer, you'd have to use another means, e.g. std::stoi:

int number = std::stoi(std::string(InputString[i]));
Comments