|
Managed C++ gives you untethered access to unmanaged code (C# can do pointers and the like, but only in an unsafe context). Managed C++ is really ugly right now though, especially with all the underscore-underscore keywords. The next version (Whidbey) of Managed C++ promises to improve the syntax of it greatly.
I guess the reason one would choose managed C++ over C# is for shear power and performance. MC++ already gives you more power than you currently have in C#, and Whidbey promises to improve on that. For example, say you created a class that inherits from ArrayList and overrides the OnAdd methods. While C# would have to adhere to the overridden methods, MC++ could actually access the underlying ArrayList and call the base methods, something not possible in C#.
For performance, Whidbey MC++ will supposedly output a .NET IL more highly optimized than any other .NET language. Of course, MC++ can always drop down into unmanaged land or even x86 assembly if you need to write extremely performance critical code.
Finally, if you need to interoperate with the C runtime library, write pure COM objects, or utilize templates, MC++ is a nice option to have.
So there you go, if you like to have fine control over everything and you need to write performance-critical code, MC++ is a nice option at your disposal. Be warned though, there are a few documented bugs using mixed managed/unmanaged code in MC++. That, plus the syntax for MC++ is proposed to change with Whidbey.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
Judah H. wrote:
While C# would have to adhere to the overridden methods, MC++ could actually access the underlying ArrayList and call the base methods, something not possible in C#.
Um, use the base keyword in C#:
public override int Add(object o)
{
base.Add(o);
} It's been available since C# 1.0.
And this stuff about performance isn't necessarily true. IL (MSIL to be exact) is still the output of the source language. While loops and the like can be optimized, the instructions to call methods, get and set properties, and similar procedures cannot. The "power and performance" argument is moot unless you call a lot of native code so that marshalling isn't really an issue in nested native calls.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Heheh yeah I know that Heath. I think you misunderstood, what I meant is that MC++ consumer code can call base methods. Any C# code can call the base method from within the inherited class, but C# consumer code of that class cannot, while MC++ consumer code can in fact do this. Take the following example
class SomeClass : ArrayList
{
public override int Add(object value)
{
if ( ((int)value) == 0 )
throw new ApplicationException("no 0's allowed!");
return base.Add (value);
}
}
ArrayList list = new SomeClass();
list.Add(0);
ArrayList* list = new SomeClass();
list::ArrayList->Add(0);
Hope that clarifies.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
Why choose one over the other? The biggest reason is to use whatever you feel most comfortable using.
Both C++ and C# can use unsafe code (i.e., manipulation of pointers) but C++ can use unverifiable code (mixed mode compilation that calls native APIs directly), which is nice in some circumstances (like when you want to use a LOT of native APIs and not have to redefine them and their supporting structs and consts in .NET structs and consts) but create problems for code hosted in remote environments (when, without changing the code groups for code access security, unverifiable code can't run).
It really doesn't matter either way, though. Pure Managed C++ and C# compile down to IL which gets JIT'd and executed at runtime when needed. These assemblies can be used by any other language that targets the CLR so the choice is yours.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
For me, some of advantages are:
1. IJW - an easy way to interoperate with unmanaged code.
2. Possibility to directly reuse existing C++ libraries.
3. RAII[^] and __nogc types in general.
4. No explicit boxing. While it looked like an iconveiniance in beginning, I quickly learned that it actually protects us from subtle, hard to fing bugs.
However, there are some dissadvantages as well:
1. It is hard to produce verifyable code with MC++.
2. Bugs[^]
|
|
|
|
|
Only place I've ever seen a positive need for MC++ is when it comes to vast chunks of native code (that isn't easily converted), or when writing Custom Marshallers. Oh, and before the Managed libraries came out for DirectX, that as well.
Jeremy Kimball
|
|
|
|
|
I need to use functionality from another dll, but I don't know the dll name and/or entry point at compile time. It will be available at runtime. I'm sure the compiler is doing something to the dllimport attribute to make it happen, so I was wondering if it's possible to do it at runtime.
Also, the dll is taking as one of it's attributes class that was written in c++ and is part of that dll. Is it possible to somehow instantiate this class in C#, populate it's fields and pass it to dll?
Thanks.
|
|
|
|
|
No, the compiler does link it, the runtime does. All the compiler does is attribute the declaration with the information you provide in the DllImportAttribute for an extern'd method. The runtime (CLR) uses the DllImportAttribute metadata to link against the native API at runtime.
If you're looking for something like LoadLibrary and GetProcAddress , then P/Invoke those methods and use them accordingly. You should be able to declare a delegate that the GetProcAddress P/Invoked method would return, but I've never tried this. Seems like with some fanagling you should be able to get this to work. Otherwise, create a native DLL that you would ship with your assembly (in a resolvable path, of course) that takes a string and some params or something then does all the loading and resolving itself.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Well, this all depends on the functionality you're using. I think Heath's just about right, you'd have to use PInvoke to load up and determine the starting proc address, but my gut is telling me that you'd probably also need to monkey around with some dynamic method invocation (dig through the System.Reflection namespace).
Are you using a COM/ActiveX component located in this DLL? Then definately the Reflection stuff: you'd need to get a dynamic Type reference, then call "InvokeMember" on it.
Is it just a chunk of procedural code within the DLL? Your only recourse may be to do the entire thing using PInvoke'd API calls: LoadLibrary, GetProcAddress, and more likely than not, CallProcEx32W.
Have fun
Jeremy Kimball
|
|
|
|
|
If I have a XML-document like this:
<Country>
<City Name = "Brussel">
<Street Name = "ghlstreet">
<Name> Test </Name>
<Age> 24 </Age>
</Street>
</City>
<City Name = "Paris">
<Street Name = "ghjstreet">
<Name> Test2 </Name>
<Age> 19 </Age>
<Street>
</City>
<City Name = "Amsterdam">
<Street Name = "gfdstreet">
<Name> Test3 </Name>
<Age> 33 </Age>
<Street>
</City>
</Country>
How can I add a street in "Paris"? Is it possible or is it to difficult?
Thx in advance!
|
|
|
|
|
Example from MSDN:
using System;
using System.IO;
using System.Xml;
public class Sample
{
public static void Main()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml("<book genre='novel' ISBN='1-861001-57-5'>" +
"<title>Pride And Prejudice</title>" +
"</book>");
XmlNode root = doc.DocumentElement;
//Create a new node.
XmlElement elem = doc.CreateElement("price");
elem.InnerText="19.95";
//Add the node to the document.
root.AppendChild(elem);
Console.WriteLine("Display the modified XML...");
doc.Save(Console.Out);
}
}
|
|
|
|
|
you will need the System.Xml namespace and something like:
string filename = "country.xml";<br />
XmlDocument countryDocument = new XmlDocument();<br />
<br />
countryDocument.Load(filename);<br />
<br />
XmlNode parisNode = countryDocument.SelectSingleNode("/Country/City[@Name = 'Paris']");<br />
<br />
XmlNode newStreetNode = countryDocument.CreateNode("Street");<br />
XmlAttribute newStreetNameAttr = countryDocument.CreateAttribute("Name");<br />
<br />
newStreetNameAttr.Value = "my new street";<br />
newStreetNode.Attributes.Append(newStreetAttr);<br />
<br />
XmlNode newStreetNameNode = countryDocument.CreateNode("Name");<br />
newStreetNameNode.InnerText = " Test 4 ";<br />
newStreetNode.AppendChild(newStreetNameNode);<br />
<br />
XmlNode newStreetAgeNode = countryDocument.CreateNode("Age");<br />
newStreetAgeNode.InnerText = " 42 ";<br />
newStreetNode.AppendChild(newStreetAgeNode);<br />
<br />
parisNode.AppendChild(newStreetNode);<br />
<br />
countryDocument.Save(filename);
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
|
Thx a lot!
But their is still a mistake i can't find.
XmlNode parisNode = countryDocument.SelectSingleNode("/Country/City[@Name 'Paris']");
An unhandled exception of type 'System.Xml.XPath.XPathException' occurred in system.xml.dll
Additional information: System error.
Do you know what is wrong with the SelectSingleNode?
Thx
|
|
|
|
|
opps typo by me. mised the equals out!
XmlNode parisNode = countryDocument.SelectSingleNode("/Country/City[@Name = 'Paris']");
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
|
Sorry to disturb you again but there is another mistake
He puts this line in yellow :
parisNode.AppendChild(newStreetNode);
An unhandled exception of type 'System.NullReferenceException' occurred in CountryAddEdit.exe
Additional information: Object reference not set to an instance of an object.
And is it possible to put Paris in a string so if i want to change another city i just have to change the string?
Thx!
|
|
|
|
|
this is because the SelectSingleNode is failing.
might be either your code or the xml file - can you post them.
the SelectSingleNode use a plain string, so you can use what ever you want for it...
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
|
string filename = @"c:\country.xml";<br />
XmlDocument countryDocument = new XmlDocument();<br />
<br />
countryDocument.Load(filename);<br />
<br />
XmlNode parisNode = countryDocument.SelectSingleNode("/Country/City[@Name = 'Paris']"); <br />
<br />
XmlNode newStreetNode = countryDocument.CreateNode(XmlNodeType.Element,"Street",null);<br />
XmlAttribute newStreetNameAttr = countryDocument.CreateAttribute("Name");<br />
<br />
newStreetNameAttr.Value = "my new street";<br />
newStreetNode.Attributes.Append(newStreetNameAttr);<br />
<br />
XmlNode newStreetNameNode = countryDocument.CreateNode(XmlNodeType.Element,"Name",null);<br />
newStreetNameNode.InnerText = " Test 4 ";<br />
newStreetNode.AppendChild(newStreetNameNode);<br />
<br />
XmlNode newStreetAgeNode = countryDocument.CreateNode(XmlNodeType.Element,"Age",null);<br />
newStreetAgeNode.InnerText = " 42 ";<br />
newStreetNode.AppendChild(newStreetAgeNode);<br />
<br />
parisNode.AppendChild(newStreetNode);<br />
countryDocument.Save(filename); <br />
countryDocument.CreateNode(XmlNodeType.Element,"Name",null);
I found this in the MSDN because there was a mistake there to but did i fill it wrong?
|
|
|
|
|
I should have just used CreateElement however, you can use CreateNode, but you don't need the null as we don't need an xml namespace.
I suspect the problem is your xml file, can you post that up.
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
|
This is the XML file (looks good in internet explorer)
<Country>
<city Name = "Brussel">
<Street Name = "ghlstreet">
<Name> Test </Name>
<Age> 24 </Age>
</Street>
</city>
<city Name = "Paris">
<Street Name = "ghjstreet">
<Name> Test2 </Name>
<Age> 19 </Age>
</Street>
</city>
<city Name = "Amsterdam">
<Street Name = "gfdstreet">
<Name> Test3 </Name>
<Age> 33 </Age>
</Street>
</city>
</Country>
|
|
|
|
|
yes, I thought so, you have changed the case of "city" in your xml...
so either change the SelectNode to be SelectSingleNode("/Country/city[@Name = 'Paris']");
or fix you xml to be "City"..
rememeber XML is case sensitive, so its best to pick on style and stick to it..
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
|
well done
the other problem:
XmlNode newStreetNode = countryDocument.CreateNode(XmlNodeType.Element,"Street",null);
I changed it into
XmlNode newStreetNode = countryDocument.CreateNode(XmlNodeType.Element,"Street","");
Now it works
Thx!
|
|
|
|
|
or you can use the short version:
XmlNode newStreetNode = countryDocument.CreateElement("Street");
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
|
off course
thx again
|
|
|
|
|
Hi all,
I have a DataGrid which show data derived from an XML file via a DataSet.
I have created an XSD Schema which is referenced in the XML (though not as a URI, just to the file) defining the types as doubles.
The XML is read with the following line (which I believe should use the schema):
myDataSet.ReadXml(fileName,XmlReadMode.Auto);
The data is sorted as strings (i.e. 1, 10, 2, 3...)
Can anyone tell me why this doesn't work properly?
---
|
|
|
|
|
jazzle wrote:
The XML is read with the following line (which I believe should use the schema):
The data is sorted as strings (i.e. 1, 10, 2, 3...)
Can anyone tell me why this doesn't work properly?
What line? Was the example enclosed in < and > brackets? Use the Preview button at the bottom of the page to check your post before you submit it.
RageInTheMachine9532
|
|
|
|