|
Hi,
several comments:
1.
I wrote an article on P/Invoke, unfortunately only part 1[^] is available so far, structs will be handled in part 2.
If you own the native code, I strongly suggest you apply my logging advice, so you can observe both managed and native worlds in one listing.
2.
your _def and _struct suffixes are a bit hard to get used to. I would drop them completely in the managed world.
3.
If I were in charge of the code at both ends, I would go for something simpler, i.e. more function calls, less data.
BTW: what happens if, suddenly, GetModules wants to return more than 4 modules?
4.
there is a potential issue in
char flashData[100];
versus
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string flashData;
[MODIFIED]
A managed string holds Unicode characters, taking 16-bit each.
The simplest equivalent of a native char array (chars are 8-bit here) would be a byte array.
[/MODIFIED]
ByValTStr derives the native character type from the CharSet attribute. You'd want an explicit CharSet=CharSet.Ansi; I admit MSDN is pretty unclear on the matter.
5.
except for the string issue, I would expect things to be correct without any further explicit marshaling, as you are basically passing a ref to one chunk of memory to be filled with ints and bytes.
6.
I don't see why the very first few ints would not be all correct. 5.
for debugging purposes, I suggest you initialize your struct members to all kinds of different silly values, so you can better see what gets filled in correctly and what doesn't. And I tend to use hex formatting while looking at such data, as that better reveals alignment problems.
Hope this helps.
|
|
|
|
|
The size of structure sent is always 4.It is fixed.
Only the ref param receives correct value from the function.
But ModuleDef[0].module[0].deviceId do not get correct value.
Does anyone know how to achieve this.
Thanks Luc Pattyn for your reply.
modified on Friday, September 24, 2010 3:30 AM
|
|
|
|
|
OK, have given this some more thought. The problem most likely is this:
due to the string issue, your data really gets marshaled, i.e. copied (as it needs a conversion between 8-bit and 16-bit characters); so both sides are not working on the same chunk of memory after all.
Now you did not specify in which direction the copy needs to take place, and there are some defaults, which don't suit your case. You probably need to add an [Out] ; have a look at the start of this article[^].
|
|
|
|
|
When I use out or ref keyword,I get System.ExecutionEngineException error.
If not specified,it compiles and run smooth, but no change in the values of struct.
I have modified the C# struct accordingly by the P/Invoke Interop Assistant result,but no gain.
What to do?.
|
|
|
|
|
I suggest you start with something simpler. Don't do "array of structs holding array of struct holding string" right away. At the very least get rid of the string, try a fixed-length byte array. The simplest first experiment would be to simply pass just a byte array of sufficient size and see if all the data gets stored in there. Remember to log it all, preferably in hex.
When the simple byte array is OK, make a struct with some actual types and the rest just a fixed-size byte array, and as long as it works let it evolve to the right thing. As soon as it fails, fix it before you add complexity.
|
|
|
|
|
I cannot change the struct in DLL,because it is used by many application.
I tried using Marshal.PtrToStructure.
But do not know how to increment the pointer.
Now the value is correct for the first array element.
Can you help in incrementing the pointer that points to the array of structures.
IntPtr pPointer;
module_Str AModule;
DeviceSize = Marshal.SizeOf(typeof(module_Str));
pPointer=Marshal.AllocHGlobal(DeviceSize*4);
GetModules(ref NumOfTestHead, pPointer, ref SW_Version);
AModule=(module_Str)Marshal.PtrToStructure(pPointer, typeof(module_Str));
DeviceId=AModule.module[0].deviceID
But how to increment the pointer to get each array element of structure,
ie.AModule[0],AModule[1] and so on..
|
|
|
|
|
I don't know. I never do such complex interfaces, they don't make sense to me.
|
|
|
|
|
I had to call a bunch of Windows APIs from C# that weren't defined in www.pinvoke.net - mostly the wifi APIs.
This tool helped a lot - it helped me generate the correct C# structures for the structs that were in the native code.
It also will let you generate equivalent C# structs for your own C structs, you just have to paste the C struct into it and it will generate the C# struct equivalent.
http://blogs.microsoft.co.il/blogs/sasha/archive/2008/01/12/p-invoke-signature-generator.aspx[^]
David
|
|
|
|
|
It is a nice tool man.
But unfortunately it does not work for my problem.
|
|
|
|
|
Finally I found a solution for my problem.
Pointer increment can be done by ToInt32() function of IntPtr and adding the Offset.
Here Offset is the size of the element in the array.
IntPtr pPointer;
module_Str AModule;
DeviceSize = Marshal.SizeOf(typeof(module_Str));
pPointer=Marshal.AllocHGlobal(DeviceSize*4);
GetModules(ref NumOfTestHead, pPointer, ref SW_Version);
int Offset=0;
for (i = 0; i<4; i++)
{
IntPtr IncrPtr = new IntPtr(pPointer.ToInt32() + Offset);
AModule=(module_Str)Marshal.PtrToStructure(IncrPtr, typeof(module_Str));
Offset = Offset + Marshal.SizeOf(typeof(module_Str));
for (j = 0; j <13; j++)
{
ListBox.Items.Add("DeviceID : " + AModule.module[j].deviceId);
ListBox.Items.Add("Version : " + AModule.module[j].version);
ListBox.Items.Add("Valid : " + AModule.module[j].valid);
ListBox.Items.Add("FlashData: " + AModule.module[j].flashData);
ListBox.Items.Add("TestHead : " + AModule.testHdId);
ListBox.Items.Add("");
}
}
Marshal.FreeHGlobal(pPointer);
|
|
|
|
|
how to deploy my project in visual studio 2010(C#)..........
plz send solution step by step...........
|
|
|
|
|
Depends on where you want to deploy it, and what type of project it is (e.g., ASP.Net web application, Windows Forms, WPF, etc.). Usually, though, you can right click on your project and select "Publish" and follow the screens presented to you.
|
|
|
|
|
It depends what you are trying to do.
If it is a web project, then you can right click on the project and deploy it to the web server, or add a web deployment project to create an installer package to deploy it to somewhere else.
It if is a windows forms or wpf project the your choices are ClickOnce deployment (vs2010 includes a wizard for this), installer package (again vs2010 has a wizard to help you create one), or even just send the user the exe to run as is.
In fact for all these vs2010 has a wizard to help you.
So...
Step one - start up vs2010 and see what you can do.
Step two - use the wizards.
Step three - when you have tried and got stuck, then ask for advice, showing what you have tried.
|
|
|
|
|
Drag and drop it on the recycle bin.
|
|
|
|
|
What's with all the smilies. Are you joking or asking a serious question?
If you are trying web deployement, you can read this [^] good blog post.
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.
My latest tip/trick
Visit the Hindi forum here.
|
|
|
|
|
In my projects I always have 4 libraries:
- Gui
- Logic
- Database
- Data structs
Usually, there are some additional libraries, but it doesn't matter.
In "Data structs" (as the name suggests) I hold all the data structures. And I always hold them in classes. And never thought they should be structs. How are you holding data structs? What advantages and disadvantages you see?
Don't forget to rate answer, that helped you. It will allow other people find their answers faster.
|
|
|
|
|
From the dictionary, a structure is:
1. a complex construction or entity
2. the arrangement and interrelationship of parts in a construction, such as a building
3. the manner of construction or organization the structure of society
4. (Life Sciences & Allied Applications / Biology) Biology morphology; form
5. (Chemistry) Chem the arrangement of atoms in a molecule of a chemical compound the structure of benzene
6. (Earth Sciences / Geological Science) Geology the way in which a mineral, rock, rock mass or stratum, etc., is made up of its component parts
7. Now rare the act of constructing
This means that you are semantically OK using a class as a structure, because you aren't referring to the struct keyword. I hope that makes sense.
|
|
|
|
|
Pete O'Hanlon wrote: I hope that makes sense
Don't know about that, but it looks classy and well structured.
|
|
|
|
|
Luc Pattyn wrote: it looks classy and well structured
But the list doesn't even start at 0.
|
|
|
|
|
Maybe zero hadn't been invented yet when Pete bought his dictionary? Anyway, it doesn't degrade the quality of the definition.
|
|
|
|
|
In most projects I quite often have occasion to think I should use a struct. But I almost always end up transforming it into a class for some reason!
Kevin
|
|
|
|
|
What is the logic as in ASP.NET application the page will not be sent if any control is not validated?
I've got dialog box with Ok and Cancel button. If any validated item (edit box) is not valid, then Ok button click should not close dialog box but only Cancel can do that?
Чесноков
|
|
|
|
|
Your question is a little confusing but I'll take a stab at your question.
You cannot use the basic MessageBox for what you want to do. You creat a form, design it as a dialog, and put your own code in the form to accomplish that.
Now if you are really sharp then you can do something like this:
Create the form and make the constructor require an IValidator class passed in the constructor. Add an OkayButton CancelButton and make the OkayButton disabled.
Define your interface for IValidator.
The Validator will implement it's own rules for what is valid and what is invalid.
As the data is entered into the form, the data is passed into the validator such that OkayButton.Enabled = Validator.IsValid( entryBox.Text );
As long as the data is valid (or once it is valid) the button will light up. As long as it is invalid it remains disabled.
By doing this, you have an extensible dialog box that can have an infinite number of validation rules without ever having to change a line of code in the control.
|
|
|
|
|
Dear Coders,
It seems that this topic is somewhat controversial.
Should we use structs in c# or not.
My projects requires a collection of data that does not fall into any specific catagory for any of my classes, but will be required for use by more than one of them.
It is a bunch of different data types where enum does not fit my needs.
I have seen structs used in c#, but have also read that whereever possible to stick with objects.
I am confused, as surely they would have been totaly replaced by objects if they should not be used?
If it is better to use objects, is it valid to create such an object that has no public or private methods other than its constructor, and instead has a bunch of public variable declerations?
Thank you
Steve
|
|
|
|
|
When in doubt, use a class instead of a struct.
Good structs are small and often short-lived (such as Point and Size).
Avoid big structs; my rule of thumb: any struct larger than 16 bytes is suspicious.
structs can do a few things classes can't; e.g. they are fine when representing value types with overloaded operators (e.g. a struct representing a complex number).
|
|
|
|