|
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
|
|
|
|
|
sorry - my mistake.
the line is added to the first post.
|
|
|
|
|
You can get a DataView from a DataTable no matter how it was created. After all, whether the records are read from a DataAdapter , added manually, or imported from an XML document, a DataSet is still constituted.
As I said before, reading data will not automatically sort your columns unless the data was already sorted. Instead, you can bind your DataGrid against a DataView which you can get from your DataTable (within the DataSet ) using either the DataTable.DefaultView or creating a new DataView , passing the DataTable over which you want the view in the constructor. See the documentation for the DataView class for more information.
Also, so that the sorting knows that a column is a number - as I mentioned before - you should create your schema. The DataSet will not resolve the schema location unless you use XmlReadMode.ReadSchema . You should still use ReadXmlSchema however, since your schema location may be different than what's used in the URI (which doesn't have to resolve to a path - it can be anything, even something like "asdf"). This way, you can also embed your schema as an embedded resource and ship it easily with your code, whereas the XML document would be arbitrary.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
How do i get to a method defined in a .lib file? There is no LIBImport attribute, but that's ok because it's a compile time import, but i'm still slightly confused. Seing how a lot of objects and methods for C and C++ are defined in them, instead of DLL's, how would i go about using them?
Now, i've found most of the methods I want in the UnsafeNativeMethods, and i'd like to call them. How do i go about that?
Cheers
Cata
|
|
|
|
|
That's because you don't use the lib's. Use the .DLL's. The lib's that you see are only used when compiling C++ code and must be included in the project.
In your C# code, use DLLImport on the DLL of the same name and don't worry about including any libraries:
<DllImport("KERNEL32.DLL", EntryPoint := "MoveFileW", _
SetLastError := True, CharSet := CharSet.Unicode, _
ExactSpelling := True, _
CallingConvention := CallingConvention.StdCall)> _
Public Shared Function MoveFile(src As String, dst As String) As Boolean
' Leave function empty - DLLImport attribute forwards calls to MoveFile to
' MoveFileW in KERNEL32.DLL.
End Function
RageInTheMachine9532
|
|
|
|
|
I'm being a total muppet here.
user32.lib, the twin to user32.dll.
It just never said use the DLL in the documentation.
I will now go and jump off a cliff.
Ciou.
Cata
|
|
|
|
|
For any decent C/C++ developer, it's pretty obvious why the .libs are documented and the .dlls aren't. .libs are used to link against (either statically or dynamically) when you link your executable (after compiling the source). The reason the .lib is documented instead of the .dll is because you don't link against a .dll, but against a .lib. When the code is executed, the .dll is loaded and mapped. The .lib basically contains the information that the executable you're linking requires in order to resolve the APIs you're using, in general terms.
Microsoft MVP, Visual C#
My Articles
|
|
|
|