|
We've noticed that calling C functions such as abs() will call into the C Runtime implementation of abs() for a Debug build but will call into System::Math::Abs in a Release build. This was pretty unexpected as the substitution of System::Math::Abs will trigger .NET exceptions such as System::OverflowException for out of bounds conditions whereas the CRT will always return a value.
For example, this will crash in Release but exit normally in Debug. Yes, it's UB so anything is possible but it also calls System::Math::Abs even if the args are normal values. This just illustrates the exception vs non-exception.
#include <cmath>
#include <stdio.h>
int main(int, char**)
{
return std::abs(INT_MIN);
}
Does anyone have any links or good search terms for this C Runtime substitution behavior they're doing? ex. Does the loader redirect calls into System:: entrypoints for things besides abs()? I'd like to see that list so I know which calls may need to be guarded with try/catch.
I can understand that they do this swap for performance purposes and to avoid extra managed->native->managed transitions but it was news to me that this was ocurring.
John
|
|
|
|
|
Microsoft Documentation allows me to change the pull down to C++ from C# but continues to shows C# syntax
#pragma once
namespace CppTutorial {
using namespace System;
using namespace System::Threading::Tasks;
public ref class MainForm : public System::Windows::Forms::Form
{
public:
MainForm(void)
{
InitializeComponent();
}
protected:
~MainForm()
{
if (components)
{
delete components;
}
}
private:
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
this->SuspendLayout();
this->AutoScaleDimensions=System::Drawing::SizeF(6,13);
this->AutoScaleMode=System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize=System::Drawing::Size(284,261);
this->Name=L"MainForm";
this->Text=L"MainForm";
this->Shown+=gcnew System::EventHandler(this,&MainForm::MainForm_Shown);
this->ResumeLayout(false);
}
#pragma endregion
public:
static void Body(int index)
{
int test=0;
}
delegate void MyDelegate(int index);
System::Void MainForm_Shown(System::Object^ sender,System::EventArgs^ e)
{
MyDelegate ^body=gcnew MyDelegate(MainForm::Body);
ParallelLoopResult ^result=Parallel::For(0,10,(System::Action <int> ^)body);
}
};
}
I know its all a bit bodged but its the only way i could get it to compile and link but the problem is obvious run time crash
System.InvalidCastException:
Unable to cast object of type 'MyDelegate' to type 'System.Action`1[System.Int32]'.
in MC++/CLI i cant find the right syntax to use for
ParallelLoopResult ^result=Parallel::For( without casting to Action
there is no generic delegate in the overides
Is there any MC++/CLI people left out there that can help or offer any other way to paralleize a for loop
i tried the old parallel_for(x,y,z){ "do stuff here" } way but
i couldnt get that very far with that either
i prefer to stick with .net but this delegate stuff omg :¬( im to old hehe
Thanks for even bothering to read this
modified 28-Jul-22 4:36am.
|
|
|
|
|
As the error says, you can't create a delegate of one type, and then cast it to a different type.
Change your code to create the correct delegate type in the first place, and remove the cast.
System::Action <int> ^body = gcnew System::Action <int>(MainForm::Body);
ParallelLoopResult ^result = Parallel::For(0, 10, body);
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you very much Richard
If MS docs had C++ version of this i would have not neded to bother you
I was very confused as i dont do delegates if i can avoid it
Very happy some C++/CLR people still exist
ill mark as solved
Here is the Final working MainForm() showing cross thread update of textBox, Random, and usage of other Member funtions
This is here to help anyone that is as bad at this overcomplicated Parallel coding in C++/CLR (my opinion should be easier)
"Parallel::For" - intellisense still moans about 2 or more overloads of it but who cares anyway, no one :¬)
namespace CppTutorial {
using namespace System;
using namespace System::Threading::Tasks;
using namespace System::Windows::Forms;
public ref class MainForm : public System::Windows::Forms::Form
{
public:
MainForm(void)
{
InitializeComponent();
}
protected:
~MainForm()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::TextBox ^textBox1;
protected:
private:
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
this->textBox1=(gcnew System::Windows::Forms::TextBox());
this->SuspendLayout();
this->textBox1->Dock=System::Windows::Forms::DockStyle::Fill;
this->textBox1->Location=System::Drawing::Point(0,0);
this->textBox1->Multiline=true;
this->textBox1->Name=L"textBox1";
this->textBox1->Size=System::Drawing::Size(563,451);
this->textBox1->TabIndex=0;
this->AutoScaleDimensions=System::Drawing::SizeF(6,13);
this->AutoScaleMode=System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize=System::Drawing::Size(563,451);
this->Controls->Add(this->textBox1);
this->Name=L"MainForm";
this->Text=L"MainForm";
this->Shown+=gcnew System::EventHandler(this,&MainForm::MainForm_Shown);
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
public:
static MainForm ^staticmain;
Random ^rand1;
static void Body(int index)
{
int r=staticmain->rand1->Next(1000000);
for(int i=0;i<r;i++){}
staticmain->textBox1->AppendText("i: "+Convert::ToString(index)+" - r: "+Convert::ToString(r)+"\r\n");
staticmain->AnotherMethod();
}
System::Void MainForm_Shown(System::Object^ sender,System::EventArgs^ e)
{
staticmain=this;
rand1=gcnew Random();
textBox1->CheckForIllegalCrossThreadCalls=false;
System::Action <int> ^body = gcnew System::Action <int> (MainForm::Body);
ParallelLoopResult ^result = Parallel::For(0, 20, body);
}
void AnotherMethod()
{
int test=1;
}
};
}
modified 29-Jul-22 3:41am.
|
|
|
|
|
What is the wrong with this code?
I simply want to show data from a datatable I have just made in a datagidview.
The code runs well but doesn't show the data. NB: the code written in c++ winforms 2022
The code:
DataTable ^dt = gcnew DataTable();
dt->Columns->Add("Name");
dt->Columns->Add("Surname");
dt->Columns->Add("Address");
dt->Columns->Add("Phone");
DataRow^ datarow = dt->NewRow();
datarow["Name"] = <pre lang="C++"> "Ahmad";
datarow["Surname"] = "Hassan";
datarow["Address"] = "Cairo";
datarow["Phone"] = "0987654321";
dt->Rows->Add(datarow);
dataGridView1->DataSource = dt;
|
|
|
|
|
Try calling dataGridView1->Refresh() after you add the data.
|
|
|
|
|
I want to write a C++/CLI wrapper class library which can be utilized in both C++ and C# applications. Step by step procedure will be more helpful along with project configurations.Basically i want to consume the c++/cli dll in both the applications. i need to write a wrapper which will be compatible with both the applications
|
|
|
|
|
i could use some tip about simplifying this code:
class Pojazd
{
public:
virtual void buduj()=0;
};
class Sedan : Pojazd
{
private:
string typ="Sedan";
public:
string marka;
string model;
int hp;
double v;
int cena;
virtual void buduj()
{
cout << marka << " " << model << " " << endl;
cout << "Typ nadwozia: " << typ << endl;
cout << "Dane Techniczne: " << endl;
cout << "-" << hp << " KM" << "\n-Silnik: " << v << "L" << endl;
cout << "Cena " << cena << "\nmiesieczna rata " << cena / 12 << endl;
}
Sedan(string nadwozie)
{
nadwozie = typ;
}
};
class Hatchback : Pojazd
{
string typ;
public:
string marka;
string model;
int hp;
double v;
int cena;
virtual void buduj()
{
cout << marka << " " << model << " " << endl;
cout << "Typ nadwozia: " << typ << endl;
cout << "Dane Techniczne: " << endl;
cout << "-" << hp << " KM" << "\n-Silnik: " << v << "L" << endl;
cout << "Cena " << cena << "\nmiesieczna rata " << cena / 12 << endl;
}
Hatchback(string typ)
{
typ = typ;
}
};
int main()
{
w:
int switch_on;
cout << "1.Sedan\n2.Hatchback"<<endl;
cin >> switch_on;
switch (switch_on)
{
case 1:
{
cout << "1.Mercedes\n2.BMW\n3.Audi\n";
cin >> switch_on;
switch (switch_on)
{
case 1:
{
Sedan Mercedes("Sedan");
Mercedes.marka = "Mercedes";
Mercedes.model = "A klasa";
Mercedes.hp = 145;
Mercedes.v = 2.1;
Mercedes.cena = 156000;
Sedan* wsk_sedan;
wsk_sedan = &Mercedes;
wsk_sedan->buduj();
}
case 2:
{
Sedan BMW("Sedan");
BMW.marka = "BMW";
BMW.model = "d531i";
BMW.hp = 166;
BMW.v = 2.5;
BMW.cena = 188770;
Sedan* wsk_sedan;
wsk_sedan = &BMW;
wsk_sedan->buduj();
}
}
}
break;
case 2:
{
}
break;
}
return 0;
}
i could continue with constructing this switch case tree sort of thingy
but i'm wondering if i can make it simpler and maybe more like a pro ( )
i dont expect ready to go code just some tip/hint so i can find more info myself
|
|
|
|
|
hshan 2022 wrote:
</div>switch (switch_on)
{
case 1:
{
Sedan Mercedes("Sedan");
Mercedes.marka = "Mercedes";
Mercedes.model = "A klasa";
Mercedes.hp = 145;
Mercedes.v = 2.1;
Mercedes.cena = 156000;
Sedan* wsk_sedan;
wsk_sedan = &Mercedes;
wsk_sedan->buduj();
}
case 2:
{
Sedan BMW("Sedan");
BMW.marka = "BMW";
BMW.model = "d531i";
BMW.hp = 166;
BMW.v = 2.5;
BMW.cena = 188770;
Sedan* wsk_sedan;
wsk_sedan = &BMW;
wsk_sedan->buduj();
}
Don't you want to add the breaks at the end of these cases?
|
|
|
|
|
if you will not add the break with case then they will execute either both after one to one
|
|
|
|
|
not relevant as i wanted to replace that method anyway my man
but yes i forgot about that
|
|
|
|
|
If you were going to give descriptions of many cars then the switch/case logic is not a good choice. Each time you add another car you need to change / compile / redistribute your application. Your descriptions of cars and their features should be outside the program.
Look at the different kinds of ways that data can be stored, including but not limited to: tables, files, arrays and lists.
You want to choose one that works long term. How many different types of cars will you include? How often will you make changes including corrections, additions and deletions? How do you want to make those updates? All these ideas need to be considered before you can choose the best solution.
|
|
|
|
|
Hi,
I need to generate the following XML codes. And Iam using VS2015.
<TALLYMESSAGE xmlns:UDF="TallyUDF">
<VOUCHER VCHTYPE="Sales" ACTION="Create">
<VOUCHERTYPENAME>Sales</VOUCHERTYPENAME>
<ALLLEDGERENTRIES.LIST>
<REMOVEZEROENTRIES>No</REMOVEZEROENTRIES>
<ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>
<LEDGERFROMITEM>No</LEDGERFROMITEM>
<LEDGERNAME>Customer 1</LEDGERNAME>
<AMOUNT>-5000</AMOUNT>
</ALLLEDGERENTRIES.LIST>
</VOUCHER>
</TALLYMESSAGE>
For That from our website quick answers, I received the following codes in C#.
[XmlRoot(ElementName="ALLLEDGERENTRIES.LIST")]
public class ALLLEDGERENTRIESLIST {
[XmlElement(ElementName="REMOVEZEROENTRIES")]
public string REMOVEZEROENTRIES { get; set; }
[XmlElement(ElementName="ISDEEMEDPOSITIVE")]
public string ISDEEMEDPOSITIVE { get; set; }
[XmlElement(ElementName="LEDGERFROMITEM")]
public string LEDGERFROMITEM { get; set; }
[XmlElement(ElementName="LEDGERNAME")]
public string LEDGERNAME { get; set; }
[XmlElement(ElementName="AMOUNT")]
public int AMOUNT { get; set; }
}
[XmlRoot(ElementName="VOUCHER")]
public class VOUCHER {
[XmlElement(ElementName="VOUCHERTYPENAME")]
public string VOUCHERTYPENAME { get; set; }
[XmlElement(ElementName="ALLLEDGERENTRIES.LIST")]
public ALLLEDGERENTRIESLIST ALLLEDGERENTRIESLIST { get; set; }
[XmlAttribute(AttributeName="VCHTYPE")]
public string VCHTYPE { get; set; }
[XmlAttribute(AttributeName="ACTION")]
public string ACTION { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName="TALLYMESSAGE")]
public class TALLYMESSAGE {
[XmlElement(ElementName="VOUCHER")]
public VOUCHER VOUCHER { get; set; }
[XmlAttribute(AttributeName="UDF")]
public string UDF { get; set; }
[XmlText]
public string Text { get; set; }
}
Is It possible to convert this From C# to Visual C++ 2015.
My heartiest thanks for all helps
Always Thank To Richard & Victor & Other Superiors, those who are having kind hearts.
Thank Again
|
|
|
|
|
You posted this question in QA[^] asking for C# code.
You've now copied someone else's C# code and want it converted to C++.
Make your damn mind up!
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
hi Richard Deeming, Sorry & Thank for the advise and the reason is Visual C++/CLR doesn't support LINQ.
I do remember all your advises are powerful & good. Your replies helped many times while I get struck.
Thank Again !
|
|
|
|
|
|
|
Stop focusing on C# code and start focusing on learning to write your own C++ XML code from scratch. You'll learn a lot more that way.
|
|
|
|
|
Hi,
Iam using Vs2015, While I try to Open a file using OpenFileDialog, Iam receiving the error
"Unhandled exception of type" System.AccessViolationException" occoured in system.windows.forms.dll
Additional information: Attempted to read or write protected memory.This is often an indication other memory is currupt.
My Codes
System::Windows::Forms::OpenFileDialog^ MyFileOpenDialog = gcnew System::Windows::Forms::OpenFileDialog();
MyFileOpenDialog->Title = "Select Your Excel Test File";
MyFileOpenDialog->InitialDirectory = "C:\\";
MyFileOpenDialog->Filter = "Excel Files (*.xls)|*.xls|All files (*.*)|*.*";
MyFileOpenDialog->FilterIndex = 2;
MyFileOpenDialog->RestoreDirectory = true;
if (MyFileOpenDialog->ShowDialog() == System::Windows::Forms::DialogResult::OK) {
MyExcelFile = MyFileOpenDialog->FileName;
}
I cannot understand my mistake !
Thanks For the helps!
Richard pls. advise me! Thank again !
modified 5-Oct-21 2:59am.
|
|
|
|
|
|
Thank Victor
|
|
|
|
|
How do I convert array to list?
array<System::Byte>^ My1DArray = gcnew array<System::Byte>(100);
to
List<System::Byte>^ temp
temp = My1DArray.ToList();
Update:
I am currently using a for loop to copy data 1 by 1, if there's no other faster way ,i'll stick with this for now . Thanks!
array<System::Byte>^ My1DArray = gcnew array<System::Byte>(100);
int^ bytesToRead = gcnew(int);
*bytesToRead = SerialPort->BytesToRead;
SerialPort->Read(My1DArray, 0, *bytesToRead);
SerialPort->DiscardInBuffer();
List<System::Byte>^ temp = gcnew List<System::Byte>;
int^ counter = gcnew (int);
for (*counter = 0; *counter < *bytesToRead; (*counter)++) {
temp->Add(My1DArray[*counter]);
}
modified 11-Jun-21 1:53am.
|
|
|
|
|
why do you care about any "other faster way"?
How long is/are the array(s) to be converted? How often are you going to convert it/them?
|
|
|
|
|
Why are you using int's through handles and gcnew?
Why don't you just say
Int32 bytesToRead = 0;
Int32 counter = 0;
??
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Hi,
i made a library in c++/cli and beside a c# program calling it. Everything works fine when i compile on any cpu or x64 on my pc (x64os/x64proc). But if i compile for x86, c# part works fine, but when i use the c++/cli part i get the error "could not load file or assembly .... incorrect format" . I use user32.lib in the c++/cli, is it possible the problem come from here ?
---- Edit
I think it's ok, i activated copy reference to output project but i'm not sure it was that.
modified 30-May-21 17:11pm.
|
|
|
|