|
Yep in the sample these are the key lines
dlg.InitModalIndirect((DLGTEMPLATE*)pBuffer);
dlg.DoModal(); // tadaaa! this is the line everyone's been waiting for!!!
I loved the tadaa in the source comments and it's because at that moment the penny should drop that the template has just been sitting in memory and wont do anything until you execute those two lines. It's much kinder on windows especially in a threaded app and less chance of making mistakes.
So when you get the message from your ethernet port all you have to do is execute those two lines and dialog flies out of memory and up on screen. You can actaully do everything else before that any earlier time.
Not sure how MFC does this but there is an lParam value that is part of the indirect and usually you pass a struct with your data you want loaded in the dialog handler in as well. It saves having to carry a global with your data.In your case I would imagine it would be a pointer to your payload data recieved. Again saves copy or moving any data.
It stuns me dlg.InitModalIndirect doesn't take a second parameter which is what I was expecting and where you would pass in your data pointer. So bit of mystery to me how you do that under MFC. Oh I wonder does dlg.InitModalIndirect have overrides and used as a shim on the indirect call to cater for that. In which case there will be a form of that you can pass a second parameter on.
In vino veritas
modified 21-Jul-17 0:11am.
|
|
|
|
|
Leon
I would assume the same is True for Modeless Dialogs I pass all my parameters once I have allocated the Cdialog Object on the Heap I populated it before doing Create Or Indirect
I have another related question can the same HGLOBAL template be used to Create multiple instances of that object
Thanks
|
|
|
|
|
Yes any dialog or window can be created from templates. The window one usually catches even seasoned programmers out. If you look at the template call CreateDialogIndirectParam the DLGPROC is optional. What you do is pass in the window handler and use setwindowlong to put it onto the modeless dialog which just happens to have all the style flags of a window. Once it has the handler attached you can just insert it into any APP window or even the desktop because it's a normal window and so you fake CreateDialogIndirectParam returning a fail. Did you notice it's up to you to call DestroyWindow and that is why they don't do it automatically. Sometimes it's useful to lie to the API
Yes its a template you can launch multiple copies as it only gets read and all global alloc memory is thread safe. It can't write or move anything as you usually only allocate just enough space to hold the resource. I assume that all still holds true for MFC. Officially the GlobalAlloc etc is now "old" but they have not got around to giving us replacement template system.
Most windows programmers are familiar with LoadResource and loading bitmap/icons/menus etc because they are going to draw them on screen alot but using the system for dialogs and windows usually escapes them because they don't need the response of a window like in your example.
In vino veritas
modified 21-Jul-17 9:50am.
|
|
|
|
|
The heap corruption indicates that you have an out of bound memory write access (e.g. writing to an array beyond it's size). Running out of memory indicates that you are allocating a lot of memory but not freeing it.
For modeless dialogs follow these adviceses:
- Create a variable and initialise it (assigning
NULL or using new )
- When the dialog should be created the first time check if the variable is
NULL and call new if so
- Create the dialog
- When finished with the dialog, call
DestroyWindow()
- If the allocated memory is not needed anymore, delete it and assign
NULL to the variable
- When the variable goes out of scope, delete the memory (e.g. in the destructor of the class holding the variable)
I suggest to check your code for the above (each new must have a corresponding delete , and each CDialog::Create must have a corresponding CDialog::DestroyWindow ).
Because the memory corruption is a severe error, I suggest to find the source and fix it first. Use a debug build. Then you don't need the GFlags. They are for debugging executable files where you don't have the sources.
If you know the code portions (or have a guess) where the heap corruption occurs, you can insert some AfxCheckMemory[^] calls to check the C++ heap.
Quote: it is after do the create of the dialog and populate the control including allocating via new a Richedit and streaming data to it that something goes wrong all storage is allocated via new A common error for such cases is forgetting to append a NULL char to the received data before passing them as string and/or forgetting to allocate the additional memory for the NULL char.
|
|
|
|
|
how to work with cards.dll
|
|
|
|
|
|
|
The article is out of date there is also a 32bit version of the DLL kicking around from Win98 and XP.
ReactOS basically duplicated most of the DLL as it is reasonably trivial
ReactOS: dll/win32/cards/cards.c Source File[^]
Find and download free deck of cards images, bind it all in Visual Studio and you have your own
In vino veritas
|
|
|
|
|
Yes, I am well aware of that, but it's the only one I know.
|
|
|
|
|
Can someone explain to me why for the following code
memcpy(&PSW+8,holdptr,8);
memcpy(&PSW,holdptr,8);
00007FF655264C1D mov rax,qword ptr [rbx+4]
00007FF655264C21 mov qword ptr [rbp+3F0h],rax
memcpy(&PSW+8,holdptr,8);
00007FF655264C28 mov rax,qword ptr [rbx+0Dh]
00007FF655264C2C mov qword ptr [rbp+530h],rax
The compiler generate a displacement of Hex 140 from the structure PSW instead of 8
struct {
BYTE sysmask;
BYTE pkey;
BYTE states;
BYTE asc;
BYTE cc;
BYTE progmask;
BYTE zerobyte;
u_int
amode64:1,
amode:1,
zeroilc:1;
char zeroword[4];
char ia[16];
char amask[4];
char intcode[2];
BYTE ilc;
BYTE unused;
} PSW;
|
|
|
|
|
You need to go and review C/C++ pointer arithmetic
Your pointer arithmetic asks it to do that .... you must have your warnings turn way down because really it should give a warning.
Since it is has escaped you, specifically what you have asked it to do is add 8 times the size of PSW to the pointer to PSW which is what it did. For some reason your expect byte operation on a pointer that isn't a pointer to a byte. If you wanted a byte operation then cast the pointer to a byte.
I can't make head nor tails of what appears to be bitcount numbers. I warn you that you need pack(1) for that, and even if packed those bitcounts don't match. It looks like some of the bit fields need unions because there seems to be variants.
I assume you were trying to point at the 8th byte in the struct but without packing it isn't guaranteed you will get what you expect. I strongly recommend you put the bitpacks in a struct so it's named and then set the pointer to the named element in the struct.
It would be a whole lot easier to pack that structure exactly as whatever those bitcounts you are writing because it seems like it's a real thing ... So make the struct match reality. This is my best guess what your struct is supposed to be and I have used the proper standard C/C++ types, it is ill advised to do such precise packing on user defined types like BYTE. C/C++ standard file stdint.h is your friend use it when not on Windows/Linux API. The uint8_t will cast to everything properly as C knows exactly what it is.
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#pragma pack(push, 1)
struct psw_s {
union {
struct variant1 {
uint8_t sysmask;
uint8_t pkey;
uint8_t states;
struct byte3_fields {
uint8_t asc : 2;
uint8_t cc : 2;
uint8_t progmask : 4;
};
union {
uint8_t zerobyte;
struct byte4_fields {
uint8_t zerobyte4 : 7;
bool amode64 : 1;
};
};
struct byte5_fields {
bool amode : 1;
bool zeroilc : 1;
uint8_t zerobyte5 : 6;
} AddrMode;
uint8_t variant1_unused[11];
};
char ia[16];
uint32_t ia32[4];
};
char amask[4];
char intcode[2];
BYTE ilc;
BYTE unused;
} PSW;
static_assert(offsetof(struct psw_s, amask) == 17, "Structure pack failed amask should be byte 17 in struct");
#pragma pack(pop)
So ia and the struct totally overlap each other they are different ways to get to same data being the 16 bytes (128 bits at the top of the struct). Array amask is at byte 17 in struct and it is checked at compile time to make dam sure it is. Compile time asserts were added in C++11 spec both GCC and VS have them as should Intel.
Anyhow now you can set the pointer to what you want by name. You can also access the bool fields. PW.AddrMode.amode is the named struct one, amode64 is in an anonymous struct so its just PW.amode64 to access. They are both just bools you can set them true/false or if test them like any bool. That shows you a named and unnamed struct bitfield access.
I think all that gets rid of the need for your pointer arithmetic as there is no field you can't hit by name.
It looks a lot like a hardware register definition I would do, but they get even worse than that
In vino veritas
modified 14-Jul-17 3:28am.
|
|
|
|
|
leon de boer wrote: you must have your warnings turn way down because really it should give a warning.
Or ignoring them. Either way a bad idea.
|
|
|
|
|
&PSW is of type "pointer to PSW", so &PSW+8 would have the same value as (PSW *)((byte *)&PSW + 8 * sizeof(PSW))
The old C pointer rules live on!
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
A mate just called and was picking my brain about how best to handle inter-process communication in plain C.
His requirement is he has a monitor app watching a process and if that process goes dark he restarts it. However, sometimes that child app is actually still functioning - it's just a little busy and doesn't respond to the monitor's pings.
What he'd like is a way to have the child process increment a counter that the monitor can watch. If the counter is incrementing then it's all good and it'll back off. If the child goes dark and the counter stops incrementing then it's time to kick it.
Any thoughts on how best to accomplish this in the simplest, most member efficient way that doesn't require the installation of something like MSMQ?
Oh, and the kicker: it needs to support Windows XP and Windows 2003. There's a lot of those installs still out there...
cheers
Chris Maunder
|
|
|
|
|
Try putting something like this into a dll:
#pragma section("SharedSection",read,write,shared)
__declspec(allocate("SharedSection")) int counter = 0;
a shared instance of counter should then be available to all instances running on the same computer that links to the dll ...
#pragma section documentation
Best regards
Espen Harlinn
Espen Harlinn
Chief Architect - Powel AS
Projects promoting programming in "natural language" are intrinsically doomed to fail. Edsger W.Dijkstra
|
|
|
|
|
|
Well,
You did not mention whether both processes are gui or a non-gui applications. So I will give an answer that will work on both... and is fairly lightweight.
It seems like he doesn't really need an IPC implementation... he is probably looking to implement a watchdog. If I were tasked with doing this I would probably go with an event object[^] in a private namespace[^].
He can even populate the lpEventAttributes parameter of CreateProcess[^] to allow the child process to inherit the event handle.
WatchDog process would simply loop and use a wait function[^] to wait for the child process to signal "I am alive" then reset the event and re-enter the wait state. If the time-out interval has elapsed and the child process has not responded... restart the process.
There are other benefits to using an event object... it can be secured with a private namespace[^].
The other answers from Espen and Leon will work just fine. Although the WM_COPYDATA method would require both watchdog and child process to be GUI threads. Both these methods are also a security risk[^] for commercial products or applications running on critical infrastructure.
Best Wishes,
-David Delaune
|
|
|
|
|
Brilliant. Thank you.
cheers
Chris Maunder
|
|
|
|
|
Named shared memory along with named synchronization objects AND monitoring process handles.
I've had apps with shared memory queues with both sides waiting on a [local] exit handle, a process handle of the other side, a semaphore and perhaps other objects.
For simple monitoring, you could combine a named semaphore and process handle.
|
|
|
|
|
I'm working on a GAME SERVER program. there is a design problem confused me.
Basic Situation:
1. the host object just as bellow has a lot of child objects. eg, 20 child objecs.
2. the host would be new and delete very frequently.
3. all the operations from the child would be invoked like this :
pHost->GetA()->DoSomething(),and also very frequently.
4. CHost1 use objects as child,CHost2 use poniter and new child in constructor.
my question is:
1. since I would new and delete CHost very ofen,may be in the server loop, is CHost2 a bad design?
2. since all the method of the child would be invoked like this:
pHost->GetA()->DoSomething(). is this indirect call cost a lot compare to
pHost->DoSomething, because it happens a lot.
If CHost2 is a bad design, I would use CHost1 or use CHost2 and a CHost2 Pool.
If Indirect call cost a lot.I would only use CHost3 without child objects,and all method would be like pHost->Dosomething
Thank you all.
ps I can't use the code button to format the code,I tried chrome and ie,why
class CHost1
{
public:
CHost1(){}
public:
C1* Get1();
C2* Get2();
CN* GetN();
private:
C1 m_1;
C2 m_2;
CN m_n;
};
class CHost2
{
public:
CHost2()
{
m_p1 = new C1;
m_p2 = new C2;
m_pN = new CN;
}
public:
C1* Get1();
C2* Get2();
CN* GetN();
private:
C1* m_p1;
C2* m_p2;
CN* m_pN;
};
|
|
|
|
|
Allocating class members on the heap is not per se bad design. It avoids for example stack overflows when the class is created on the stack and the members use a lot of memory.
But allocating and freeing memory frequently reduces the performance significantly. So the Host2 option seems to be the best option for you. If the members use so much memory that stack overflows might occur, create Host2 always on the heap using new .
The indirections should not be a problem. The overhead is very small compared to heap allocation. Some indirections may be also removed by the compiler. And you might not be able to remove them because with your example I did not see a chance to do that:
CHost::GetA() { return &m_A; }
CA::DoSomething { }
pHost->GetA()->DoSomething();
pHost->&m_A->DoSomething();
pHost->m_A.DoSomething();
CHost::DoSomethingWithA() { m_A.DoSomething(); }
pHost->m_A.DoSomething(); As you can see both methods are not really different.
|
|
|
|
|
It is actually the situation where you use a delegate.
It is very common on game servers which are doing things like guns/projectiles etc to do this. The reason is you want to bind a behaviour to a random class without worrying what the class is and going thru the issue you have. So when I have a bullet I don't care if it's a 50 cal, 45 magnum or a BB pellet it has a behaviour and I will execute the delegate function to move it and use the payload to hold a callback for the object to draw itself and vary the damage etc. The classes don't even have to be related to use a delegate they can have random relationships and it's safe.
So unlike a class/object a delegate is an action or an event and generally it carries a payload which can be other actions or objects. You called your function DoSomething and it goes to another object
The other cute thing is you can add and delete delegates at any time to an object and you can test for the presence of a delegate. So you can add/delete and turn on/off functionality to a class/object with ease without the class itself needing to know or building that functionality on all related classes.
All real game engines do it that way and typically your server connects to players etc via delegates. Usually it is just doing things like scoring etc and removing dead people etc so it doesn't care what the objects are it just needs a couple of things from them. The last thing you want the server doing is get involved heavily in the objects or you will bottleneck everything. When an object disconnects from the server it simply removes itself from the server multicast delegates and the server will no longer see it and it's free to delete itself or whatever in it's own good time. So typically a server doesn't get involved in creating or deleting objects either which is the responsibility of a spawn system(s).
Delegates | Unreal Engine[^]
Unity - Delegates[^](worth watching the video to see it's use in a game)
Unreal Engine has the classical layout (look at the block diagram at bottom) .. GameServer sits alone things only join
Gameplay Framework Quick Reference | Unreal Engine[^]
There are a number of articles on C/C++ delegates on this site and good old google will throw hundreds and obviously MS has a sample as Visual Studio has them.
delegate (C++ Component Extensions)[^]
You might also want to look at C++ Events which we sometimes use in place of a delegate
In vino veritas
modified 11-Jul-17 23:04pm.
|
|
|
|
|
Jochen Arndt,leon de boer
thank you very much,it's really a great help. Now I know how to do it.
|
|
|
|
|
I'm working on a server program. there is a design problem confused me.
|
|
|
|
|
que.1
Delete the least number of integers from a given set of integers so that the product of the remaining integers in the set is a perfect square. In case there is more than one solution then find the solution that gives the largest perfect square. Assume that each integer contains five or less number of digits. The total number of integers in the given set is twenty or less.
Input (Q3.in)
First line will be number of test cases
The input may contain multiple test cases.
For each test case there is a single input line. The line contains the given set of integers. The
Output (Q3.out)
For each test case there is only one output line. The line simply prints the integers to be deleted
in ascending order. There are two special cases; print output for these cases as indicated below.
Case 1: No integer is to be deleted: Print 0 as output.
Case 2: All integers are to be deleted: Print all integers in ascending order.
Sample Input
4
2 3 12 18 24
12 10 15 18
4 12 10 15.
|
|
|
|