|
Thanks for your reply. I shall make a note of it every time I post some code snippets.
"Class" is just an example my actual Class is not named as "Class".
|
|
|
|
|
Hi , Is it possible to run the downloadAttachment method on a different thread , so that the users are not interrupted when the proces is runnin?
|
|
|
|
|
Hi,
I have an object that performe a security check before setting a property
Class Issue
string _status
string Status {
set {
if (Value == "urgent" && current.User.IsManager)
_status = "urgent"
else
throw exception
}
get { return _status}
}
The problem arise when I just need to fill the status property from data coming from the Database.
Is there any proper OO way to leave the business logic in the object while allowing at least the db layer to fill this proerty?
At the moment, I have a IssueManager that is responsible to execture CRUD methods on the DB on behalf of Issue.
Thanks
|
|
|
|
|
pierpaolo paparo wrote: Is there any proper OO way to leave the business logic in the object
Probably not the correct OO way to do it, we use a bool flag bLoading to short circuit this problem.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Hi,
What would be the proper OO way?
How do you use the bLoading bool flag?
Pierpaolo
|
|
|
|
|
Have a local bool bLoading default to true, when the constructor is completed set bLoading to false
In the status check put the following
if(bLoading){return;}
in the first line.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Have the IssueManager class create the Issue object by means of a constructor that doesn't do a security check. If, for whatever reason, that won't work for you, you could always default to using reflection to manually set the _status field after instantiating the object.
Adam Maras | Software Developer
Microsoft Certified Professional Developer
|
|
|
|
|
Hi,
This could be a viable solution
Thanks
|
|
|
|
|
No problem
Adam Maras | Software Developer
Microsoft Certified Professional Developer
|
|
|
|
|
Yeah, a constructor that only the DB code uses.
Or maybe in serialization/deserialization code.
|
|
|
|
|
sample code :
Hashtable h0 = new Hashtable();
h0.add(0,10);
Hashtable h1 = new Hashtable();
h1.add(0,h0);
h1.Remove(0);
Question:
do i need to get the h0,remove the items in h0,then remove the h0 from h1?or just remove the h0?
|
|
|
|
|
Hi,
no you don't need to dismantle an element that you want to remove from a collection.
BTW: you should consider using generic collections (such as Dictionary<T1,T2> ), available since .NET 2.0; they are faster and safer.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
I'm using some midi API functions that take a MIDIHDR structure.
[StructLayout(LayoutKind.Sequential)]
public struct MIDIHDR
{
public IntPtr lpData;
public int dwBufferLength;
public int dwBytesRecorded;
public IntPtr dwUser;
public int dwFlags;
public IntPtr lpNext;
public IntPtr reserved;
public int dwOffset;
public IntPtr dwReserved;
} lpData is a pointer to the data. This data is an array of MIDIEVENT structures
[StructLayout(LayoutKind.Sequential)]
public struct MIDIEVENT
{
public uint dwDeltaTime;
public uint dwStreamID;
public uint dwEvent;
} If I only have one element in the array I can use
int eventSize = Marshal.SizeOf(ev) * events.Length;
IntPtr eventPointer = Marshal.AllocHGlobal(eventSize);
for (int i = 0; i < events.Length; i++)
Marshal.StructureToPtr(events[i], (IntPtr)((int)eventPointer + (eventSize * i)), false); but I get Arithmetic operation resulted in an overflow when the second event is reached when playing the events (midiStreamRestart(handle) ) if there is more than one element.
So, what's the best way to marshal an array of structures, and why doesn't the above work?
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
modified on Friday, August 14, 2009 6:20 PM
|
|
|
|
|
I suspect you'll have to decorate lpData with
[MarshalAs(UnmanagedType.LPArray)] . Turn it into
[[MarshalAs(UnmanagedType.LPArray)]
IntPtr[] lpData; It's late here in the UK though, so my thinking may be a bit fuzzy here.
Ignore this - I hadn't noticed that lpData was pointing to MIDIEVENT, and this won't work in this situation.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
modified on Friday, August 14, 2009 5:58 PM
|
|
|
|
|
I'm going to disagree. An array of structs just aggregates all the data in a single memory block,
it isn't an array of reference types, just one pointer to lots of data.
The Win32 function SendInput() is an example, in fact it is the example I got working some months ago.
Pete O'Hanlon wrote: It's late here in the UK
I trust Dave has noticed that too.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
I must admit, I didn't look at what lpData was pointing to, I just read the line that lpData was the array - I really should have read it through fully. You're exactly right - this code won't work, so I'm going to amend the post.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Luc Pattyn wrote: I trust Dave has noticed that too.
Yeah, my Mrs just pointed it out!
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Hi Dave,
I have avoided such complexities till now, except for once, a rather simple variable array length.
Here are the results of the Antwerp jury:
In
[1] int eventSize = Marshal.SizeOf(ev) * events.Length;
[2] IntPtr eventPointer = Marshal.AllocHGlobal(eventSize);
[3] for (int i = 0; i < events.Length; i++)
[4] Marshal.StructureToPtr(events[i], (IntPtr)((int)eventPointer + (eventSize * i)), false);
There is something fishy about eventSize;
[1] is an attempt to compute the overall size; it may be correct, I am not sure, as Sizeof(ev) is the size of one struct and could be rounded up to a multiple of 16 or so, whereas an array would not contain padding bytes between elements.
And [4] treats eventSize as if it were the size of a single element, which it isn't. So that is probably the direct cause of your overflow.
Seems like you want to move the multiplication from [1] to [2].
FWIW: IntPtr will adapt to Win32/Win64 as you probably know; don't let it fool you.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Luc Pattyn wrote: I have avoided such complexities till now, except for once, a rather simple variable array length.
That's why I use C++/CLI when I need to.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
For me, that is just replacing one problem by another one, as I have almost zero experience with C++/CLI.
I prefer staying in charge of both sides (C# and native) and choose a simpler interface, one that does not need any marshaling at all.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Luc Pattyn wrote: choose a simpler interface, one that does not need any marshaling at all
Unfortunately, some of our suppliers provide unmanaged code with complex structures that's just easier to cope with in mixed languages. We use CLI to simplify the interfaces for our use.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Yep, when the interface is fixed, there isn't much one can do.
My data typically is large and doesn't like to get copied just for marshalings' sake. In simulation, image processing, and such, the performance gained by doing things natively should not be thrown away by merely crossing the boundary.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
eventSize is actually 12 * number of elements. The Marshal.SizeOf(ev) was there from previously attempted code and is now redundant - sorry about that.
Luc Pattyn wrote: [4] treats eventSize as if it were the size of a single element, which it isn't
Not sure what you mean here. I'm trying to Marshal element[i] into the next block of bytes reserved by [2], so if there were three elements, [2] would reserve 36 bytes. On the first iteration, element 1 will go to where eventPointer is pointing, on the second eventPointer + 12, on the third eventPointer + 24.
Oops - you're right. eventSize is the size of all events, not an individual. Changing that in [4] fixed it!
Thanks guys.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
you're welcome.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
In case you're interested - this is the working test code.
This is just for testing - the actual app will have lots of error checking/exception catching, the PInvoke stuff will be alot safer, stuff will be handled in threads and events used to unprepare buffers and close streams etc... but it shows how complicated something like this can be to get just right!
using System;
using System.Runtime.InteropServices;
namespace MIDITest
{
public delegate void MidiProc(IntPtr hMidiIn, int wMsg, int dwInstance, uint dwParam1, uint dwParam2);
class Program
{
static void Main(string[] args)
{
MIDI midi = new MIDI();
midi.BrokenCMajorTriad();
Console.ReadKey();
}
}
class MIDI
{
MidiProc midiProc;
public void BrokenCMajorTriad()
{
midiProc = MessageHandler;
int id = 0;
IntPtr handle = IntPtr.Zero;
int result = 0;
Console.WriteLine("Stream Out Message");
Console.WriteLine("------------------");
MIDIHDR header = new MIDIHDR();
MIDIEVENT ev0 = new MIDIEVENT();
ev0.dwEvent = 0x00403C90;
MIDIEVENT ev1 = new MIDIEVENT();
ev1.dwDeltaTime = 10;
ev1.dwEvent = 0x00404090;
MIDIEVENT ev2 = new MIDIEVENT();
ev2.dwDeltaTime = 10;
ev2.dwEvent = 0x00404390;
MIDIEVENT ev3 = new MIDIEVENT();
ev3.dwDeltaTime = 80;
ev3.dwEvent = 0x00403C80;
MIDIEVENT ev4 = new MIDIEVENT();
ev4.dwDeltaTime = 0;
ev4.dwEvent = 0x00404080;
MIDIEVENT ev5 = new MIDIEVENT();
ev5.dwDeltaTime = 0;
ev5.dwEvent = 0x00404380;
MIDIEVENT[] events = new MIDIEVENT[]
{
ev0, ev1, ev2, ev3, ev4, ev5
};
int eventSize = Marshal.SizeOf(typeof(MIDIEVENT));
int blockSize = eventSize * events.Length;
IntPtr eventPointer = Marshal.AllocHGlobal(blockSize);
for (int i = 0; i < events.Length; i++)
Marshal.StructureToPtr(events[i], (IntPtr)((int)eventPointer + (eventSize * i)), false);
result = midiStreamOpen(ref handle, ref id, 1, midiProc, 0, CALLBACK_FUNCTION);
header.lpData = eventPointer;
header.dwBufferLength = blockSize;
header.dwBytesRecorded = blockSize;
int headerSize = Marshal.SizeOf(header);
IntPtr headerPointer = Marshal.AllocHGlobal(headerSize);
Marshal.StructureToPtr(header, headerPointer, false);
result = midiOutPrepareHeader(handle, headerPointer, headerSize);
result = midiStreamOut(handle, headerPointer, headerSize);
result = midiStreamRestart(handle);
while (((BufferFlags)Marshal.ReadInt32(headerPointer, 16) & BufferFlags.Done) != BufferFlags.Done)
{ }
result = midiOutUnprepareHeader(handle, headerPointer, headerSize);
Marshal.FreeHGlobal(headerPointer);
Marshal.FreeHGlobal(eventPointer);
System.Threading.Thread.Sleep(2000);
result = midiStreamClose(handle);
handle = IntPtr.Zero;
}
void MessageHandler(IntPtr hMidiIn, int wMsg, int dwInstance, uint dwParam1, uint dwParam2)
{
switch (wMsg)
{
case MOM_OPEN:
Console.WriteLine("Opened");
break;
case MOM_CLOSE:
Console.WriteLine("Closed");
break;
case MOM_DONE:
Console.WriteLine("Done");
break;
}
}
[Flags]
public enum BufferFlags
{
None = 0,
Done = MHDR_DONE,
Prepared = MHDR_PREPARED,
Queued = MHDR_INQUEUE,
ISStream = MHDR_ISSTRM
}
public const int CALLBACK_FUNCTION = 0x00030000;
public const int MOM_OPEN = 0x3C7;
public const int MOM_CLOSE = 0x3C8;
public const int MOM_DONE = 0x3C9;
public const int MHDR_DONE = 0x00000001;
public const int MHDR_PREPARED = 0x00000002;
public const int MHDR_INQUEUE = 0x00000004;
public const int MHDR_ISSTRM = 0x00000008;
[DllImport("winmm.dll")]
public static extern int midiOutPrepareHeader(
IntPtr hmo,
IntPtr lpMidiOutHdr,
int cbMidiOutHdr);
[DllImport("winmm.dll")]
public static extern int midiOutUnprepareHeader(
IntPtr hmo,
IntPtr lpMidiOutHdr,
int cbMidiOutHdr);
[DllImport("winmm.dll")]
public static extern int midiStreamClose(
IntPtr hStream);
[DllImport("winmm.dll")]
public static extern int midiStreamOpen(
ref IntPtr lphStream,
ref int puDeviceID,
int cMidi,
MidiProc dwCallback,
int dwInstance,
int fdwOpen);
[DllImport("winmm.dll")]
public static extern int midiStreamOut(
IntPtr hMidiStream,
IntPtr lpMidiHdr,
int cbMidiHdr);
[DllImport("winmm.dll")]
public static extern int midiStreamRestart(
IntPtr hms);
}
[StructLayout(LayoutKind.Sequential)]
public struct MIDIHDR
{
public IntPtr lpData;
public int dwBufferLength;
public int dwBytesRecorded;
public IntPtr dwUser;
public int dwFlags;
public IntPtr lpNext;
public IntPtr reserved;
public int dwOffset;
public IntPtr dwReserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct MIDIEVENT
{
public uint dwDeltaTime;
public uint dwStreamID;
public uint dwEvent;
}
}
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|