|
You can define a path for the assemblyname.xml file in your project's properties.
If this XML documentation has the same name as the DLL, IntelliSense will find it in the folder that contains the assembly and display the summaries.
|
|
|
|
|
Go into your Project Properties, Configuration Properties, Build, and make sure that XML Documentation File is set to the same filename with an XML extension as your assembly. For instance, if your target filename is myAssm.DLL, then your XML Doc filename should be myAssm.DLL.XML.
RageInTheMachine9532
|
|
|
|
|
Actually, just myAssm.xml is fine. This is how the FCL XML documentation is named as well.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
XmlNode test = xml.SelectSingleNode("/session/parameters/developmentsession");<br />
if (test.InnerText.ToString() = "true")<br />
chkDevelopment.Checked = true;<br />
else chkDevelopment.Checked = false;
what is wrong with this if-structure? The compiler says
Cannot implicitly convert type 'string' to 'bool'
Thx in advance
|
|
|
|
|
do you mean this :
if (test.InnerText.ToString() == "true")
|
|
|
|
|
yes that's it
sorry stupid mistake
|
|
|
|
|
Actually, that's not really correct, either. What if it's "True"? It's better to use Convert.ToBoolean(String) or something like that, if all you're expecting is a boolean string, or false for anything else that isn't some variant of "true".
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
When you do string comparisons, the string class has a static method to help you. Try the following:
XmlNode test = xml.SelectSingleNode("/session/parameters/developmentsession");
if(string.Compare(test.InnerText, "true", true) == 0)
chkDevelopment.Checked = true;
else
chkDevelopment.Checked = false;
- Nick Parker My Blog | My Articles
|
|
|
|
|
I've asked this question a month ago, but have had the flu , so now I try again.
I used this code and compiled it in VS2002 and it works fine.
#region Key events
protected override void OnKeyDown(KeyEventArgs kea)
{
switch (kea.KeyData)
{
case Keys.Enter:
...
..
break;
case Keys.Escape:
this.Close();
break;
}
}
#endregion
The class is deriving from System.Windows.Forms.Form
I then compiled it in VS2003 and it woudn't enter the method when I make
a key event like Esc or any other.
Anyone knows why?
Thanks
Thomas
|
|
|
|
|
Either it's not loaded or there was some breaking change. Read the Visual Studio 2003 documentation (not the .NET Framework SDK, mind you) for more information on the DTE object model to see if anything has changed.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi,
I have a structure defined in a dll which has another structure array as a member. I need to call this Dll from C#. How do I do it?
This is the structure I have in the DLL.
typedef struct FIRST_STRUCT
{
double XSpeed;
int DRate;
unsigned int RotCtrl
} FIRST_STRUCT;
typedef struct SEC_STRUCT
{
char Model[20];
unsigned int SuptTxt;
FIRST_STRUCT CurSpd;
FIRST_STRUCT MaxRdSpd;
unsigned int cNumSpd;
FIRST_STRUCT CrwWrd[40];
FIRST_STRUCT DWrd[20];
} SEC_STRUCT;
__declspec (dllexport) unsigned int CALLBACK MyFunc(SEC_STRUCT * Info);
_________________________________________________________________________
How do I call this from my C# client? I have changed the structure as
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct First_struct
{
public System.Double XSpeed;
public System.Int32 DRate;
public System.UInt32 RotCtrl;
}
How do I marshal the SEC_STRUCT in C#. I tired using the MarshalAs(), but it gave me a run time error 'System.TypeLoadException'
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public First_struct[] CrwWrd;
Kindly Help.
Thanks
Vini
|
|
|
|
|
What was the full message of the exception?
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Heath Stewart wrote:
What was the full message of the exception?
An unhandled exception of type 'System.TypeLoadException' occurred in MyProj.exe
Additional information: Can not marshal field CrwWrd of type FIRST_STRUCT: This type can not be marshaled as a structure field.
kindly help..
Vini
|
|
|
|
|
Marshalling nested structs is not supported in the .NET Framework. Instead, you need to marshal them as IntPtr s using Marshal.StructureToPtr and back using Marshal.PtrToStructure :
[StructLayout(LayoutKind.Sequential)]
public struct FirstStruct
{
[MarshalAs(UnmanagedType.R4)] public double XSpeed;
[MarshalAs(UnmanagedType.SysInt)] public IntPtr DRate;
[MarshalAs(UnmanagedType.SysUInt)] public IntPtr RotCtrl;
public FirstStruct(double XSpeed, long DRate, long RotCtrl)
{
this.XSpeed = XSpeed;
this.DRate = new IntPtr(DRate);
this.RotCtrl = new IntPtr(RotCtrl);
}
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct SecondStruct : IDisposable
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=20)] public string Model;
[MarshalAs(UnmanagedType.SysUInt)] public IntPtr SuptText;
public IntPtr CurSpd;
public IntPtr MaxRdSpd;
[MarshalAs(UnmanagedType.SysUInt)] public IntPtr cNumSpd;
public IntPtr CrwWrd;
public IntPtr DWrd;
public SecondStruct(string Model, long SuptText, FirstStruct CurSpd,
FirstStruct MaxRdSpd, long cNumSpd, FirstStruct[] CrwWrd,
FirstStruct[] DWrd)
{
if (CrwWrd == null || DWrd == null)
throw new ArgumentNullException(CrwWrd == null ? "CrwWrd" : "DWrd");
if (CrwWrd.Length > 40) throw new ArgumentException("Error", "CrwWrd");
if (DWrd.Length > 20) throw new ArgumentException("Error", "DWrd");
this.Model = Model;
this.SuptText = new IntPtr(SuptText);
this.cNumSpd = new IntPtr(cNumSpd);
GCHandle handle = GCHandle.Alloc(CurSpd);
this.CurSpd = handle.AddrOfPinnedObject();
handle = GCHandle.Alloc(MaxRdSpd);
this.MaxRdSpd = handle.AddrOfPinnedObject();
handle = GCHandle.Alloc(CrwWrd);
this.CrwWrd = handle.AddrOfPinnedObject();
handle = GCHandle.Alloc(DWrd);
this.DWrd = handle.AddrOfPinnedObject();
}
void IDisposable.Dispose()
{
GCHandle handle = (GCHandle)this.CurSpd;
if (handle.IsAllocated) handle.Free();
handle = (GCHandle)this.MaxRdSpd;
if (handle.IsAllocated) handle.Free();
handle = (GCHandle)this.CrwWrd;
if (handle.IsAllocated) handle.Free();
handle = (GCHandle)this.DWrd;
if (handle.IsAllocated) handle.Free();
this.Model = null;
GC.SurpressFinalize(this);
}
}
[return: MarshalAs(UnmanagedType.SysUInt)]
public delegate IntPtr MyFunc(ref SecondStruct Info); This should work. If you have problems with it, see http://www.dotnet247.com/247reference/msgs/24/121227.aspx[^] for another way where you actually alloc each struct and struct array member in global memory. Since structs are allocated on the stack, I only pin and get the address of the first member (the array address) since the unmanaged code should easily get the array from the start address. You might want to add additional code to make sure, however, that the arrays are exactly 40 or 20 elements in size.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Heath Stewart wrote:
// Define the callback.[return: MarshalAs(UnmanagedType.SysUInt)]public delegate IntPtr MyFunc(ref SecondStruct Info);
This should work.
Thanks Very much. But I am not fully clear.
__declspec (dllexport) unsigned int CALLBACK MyFunc(SEC_STRUCT * Info);
This is the function exported by the C++ Dll. How should I call this function from my C# client?
[DllImport("MyDll",CallingConvention=CallingConvention.Cdecl)]
public extern static System.UInt32 MyFunc(ref SecondStruct Info) ;
private void button1_Click(object sender, System.EventArgs e)
{
FirstStruct[] first= new FirstStruct[40];
...
SecondStruct info = new SecondStruct(....,first,...);
System.UInt32 uRet= MyFunc(ref info);
MessageBox.Show(info.Model);
...
}
Is this code correct? How to marshal the SecondStruct to IntPtr using Marshal.StructureToPtr and back using Marshal.PtrToStructure ?
Pls Help. Thanks
Vini
|
|
|
|
|
What I did is an alternative to Marshal.StructureToPtr and Marshal.PtrToStructure (along with using Marshal.AllocHGlobal ). Either way should work.
The reason I define MyFunc as a delegate is because the native signature declared it as a CALLBACK . This indicates (though for your circumstances, I may be wrong) that you don't actually call this method, but simply pass it as a callback to some other function.
If you were to declare it as a P/Invoke method, it would look like this:
[DllImport("mydll.dll")]
private static extern uint MyFunc(ref SecondStruct s);
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks.. Couldn't quite get it correct. The structure is passed to the function in dll as reference. If I declare the structure array variable as IntPtr, should I use pointer arithematics to read the value back from the structure array member of the struct?
Tnx
Vini
|
|
|
|
|
More than likely, this is going to be necessary. See the Marshal class documentation, though, for some methods that may ease the process a little.
One more thing you should consider if you can modify the unmanaged code is a thunking layer. Basically, these come in handy when you have marshaling problems such as this. For example, you could define a method with takes all the fields as parameters for the first and second struct and then assembles them internally into the second struct, which it then calls the unmanaged function you are now. Using this approach, you'd be able to easily marshal members of both of the structs.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Sorry about this. I very much appretiate your help . Still a basic doubt:
Heath Stewart wrote:
[StructLayout(LayoutKind.Sequential)]
public struct FirstStruct
{
[MarshalAs(UnmanagedType.R4)] public double XSpeed;
[MarshalAs(UnmanagedType.SysInt)] public IntPtr DRate;
[MarshalAs(UnmanagedType.SysUInt)] public IntPtr RotCtrl;
public FirstStruct(double XSpeed, long DRate, long RotCtrl)
{
this.XSpeed = XSpeed;
this.DRate = new IntPtr(DRate);
this.RotCtrl = new IntPtr(RotCtrl);
}
}
Is there any problem if I declare the structure as
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct FirstStruct
{
public System.Double XSpeed;
public System.Int32 DRate;
public System.UInt32 RotCtrl;
}
If I want to call a function from a dll written in C++ from my c# client, what should I do? Should I create a similar C# structure with managed DataTypes and use that to call the c++ dll function from my C# client, then use it to get the values returned by the Dll
OR
Should I create a similar structure in C# with Unmanaged Type data and then pass it to the function exported by the Dll and use the values returned?
Is the above both declaration one and the same? I have used [MarshalAs(UnmanagedType.ByValTStr, ....)] only in places where the variable declared was char[].
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)] public string Vendor;
When I debug the program, at the function call I get an 'ExecutionEngineException' . Is it the problem which the marshaling of the structure array?
Kindly help.
Vini
|
|
|
|
|
First, in your declaration it is more desirable to use the intrinsic keywords instead of their actual types, like double instead of System.Double . Either way works, but the former makes your code more readable. They are the same thing, after all.
The problem with declaring the last two as int and uint is that a native int and unsigned int are actual processor dependent. So, if this was running on a 64-bit processor, your struct wouldn't marshal correctly. An Int32 (int ) will always be 32 bits, meaning that your field alignment will be incorrect and you'll get invalid values. That's why I declared them as IntPtr and made the parameters long (to allow for large enough numbers, although your values may never be more than 32 bits).
No matter how you declare your structs, the problem is that nested structures can't be marshalled by the CLR. That's why I suggested a thunk. You could declare a native function and P/Invoke that like so:
[DllImport("whatever.dll", CharSet=CharSet.Ansi)]
private static extern IntPtr MyFuncThunk(
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=20)] string Model,
[MarshalAs(UnmanagedType.SysUInt)] IntPtr SuptText,
FirstStruct CurSpd,
FirstStruct MaxRdSpd,
[MarshalAs(UnmanagedType.SysUInt)] IntPtr cNumSpd,
[MarshalAs(UnmanagedType.ByValArray, SizeConst=40)] FirstStruct[] CrwWrd,
[MarshalAs(UnmanagedType.ByValArray, SizeConst=20)] FirstStruct[] DWrd);
[DllImport("whatever.dll")]
private static extern IntPtr MyFunc(IntPtr Info); You pass your data to the thunk which allocs and initializes the struct (SEC_STRUCT ), then returns the address to the struct (a pointer). You can use that pointer then in the call to MyFunc , although I still wonder if you really want to P/Invoke this since the function is most likely not exported, being that it's a CALLBACK . The one way to find out is to load your DLL into depends.exe (comes with the Platform SDK tools, which is installed by default with Visual Studio) and look at the exports.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks. But my function eventhough declared as a call back, is called by the UI. I already have a c++ client which uses this dll and calls the said function. I am trying to build a similar client in C#. As far as writing another method is concerned, I have got only the .dll file and the .h file with me. source code is not available.
I have used the depends.exe, which shows me an entry to the above mentioned function as _MyFunc@4 in the dll. Any idea??
Vini
|
|
|
|
|
In your DllImportAttribute , set EntryPoint="_MyFunc@4" . If you can't modify the source, you'll have to manually marshal the nested structs as I mentioned before by either pinning the first struct or using the appropriate Marshal methods.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thank You very much...
Finally I think I am getting everything right. I used the method of pinning the first structure , which u mentioned in one of your previous post. Tnx a lot.
cheers
Vini
|
|
|
|
|
Hai Vini Deep,
My need is same as your problem.
Please reply if you have solved it.
Thanks friend.
|
|
|
|
|
To know who was pinging me, I wrote a little program as following:
using System;
using System.Net;
using System.Net.Sockets;
class Class1
{
static void Main(string[] args)
{
Socket sock=new Socket(AddressFamily.InterNetwork,SocketType.Raw,ProtocolType.Icmp);
sock.Bind(new IPEndPoint(IPAddress.Any,0));
byte[] buf=new byte[65535];
EndPoint ep=new IPEndPoint(IPAddress.Any,0);
while(true)
{
int len=sock.ReceiveFrom(buf,ref ep);
if(len<0) continue;
Console.WriteLine("Received {0} byte(s) from {1}",len,((IPEndPoint)ep).Address);
}
sock.Close();
}
}
However, it didn't work at all!
When my friend pinged me from his pc, my pc gave no output!!
When I ran the command "ping 127.0.0.1 -n 1", it output "Received 60 byte(s) from 127.0.0.1", but
in fact it should have output 2 lines--one for icmp echo, the other for icmp echo-reply !!
Why??
It is a bug of the implementation of MS's dotnet framework?
Please help me and I will be quite grateful.
|
|
|
|
|