|
Consider the following:
class A
{
recipient;
queue;
};
class B
{
recipient;
queue;
text;
from;
};
A a;
B b;
if (some_condition)
modify a.recipient, a.queue;
else
modify b.recipient, b.queue, b.text, b.from;
...
if (some_condition)
modify a.recipient, a.queue;
else
modify b.recipient, b.queue, b.text, b.from; This code that modifies the various members is repeated dozens of times. I would like to somehow instantiate just one of either A or B so that the code that modifies the common member variables can do so without having to use a runtime condition. Something like:
modify b.recipient, b.queue;
if (some_condition)
modify b.text, b.from; I thought that I could put the common member variables into a base class and derive A and B from that, but nothing I tried would satisy the compiler. Modify the member variables through the base class and it would complain about text and from . Modify the member variables through the derived class and it would complain about recipient and queue .
One or other of the two classes will eventually be sent to another computer. That computer is expecting data of a certain size. In other words, I can't operate on B if the other computer is expecting A and vice versa.
Thanks,
DC
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
From the top of my head, what about a virtual function to do the modify operation? I know that goes against your requirement of having to use a runtime condition, but that's the best or most consistent runtime condition to rely on, I think.
Chris Meech
I am Canadian. [heard in a local bar]
Remember that in Texas, Gun Control is hitting what you aim at. [Richard Stringer]
Nice sig! [Tim Deveaux on Matt Newman's sig with a quote from me]
|
|
|
|
|
Derive B from A. Try operating from the derived class. Now I think you can access all member variables of A as well as B.
Just a thought.
<marquee direction="up" height="30" scrolldelay="1" step="1" scrollamount="1" hspace="0" vspace="0">
--Owner Drawn
--Nothing special
--Defeat is temporary but surrender is permanent
--Never say quits
--Jesus is Lord
|
|
|
|
|
If the computer that will eventually receive this data is expecting A and I send it (a larger) B, those extra bytes will cause all sorts of data loss due to everything being shifted.
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
DavidCrow wrote: If the computer that will eventually receive this data is expecting A and I send it (a larger) B, those extra bytes will cause all sorts of data loss due to everything being shifted.
Well now you are adding contraints that weren't in your original question.
Also your comment above isn't true, it depends on how your network code is set up.
The simplest way would be to add a Serialize method to A/B to read/write the object state to a blob of memory (e.g. in XML format) and then send the blob across the network.
But this issue (sending the data across a network) is unrelated to the original problem of optimizing your code.
...cmk
Save the whales - collect the whole set
|
|
|
|
|
cmk wrote: Well now you are adding contraints that weren't in your original question.
This constraint was not mentioned as it is irrelevant as far as my question goes.
cmk wrote: Also your comment above isn't true, it depends on how your network code is set up.
It's entirely true. I know how the data has to be packaged before it can be sent.
My question was nothing more than a C++ question. It has nothing to do with the network.
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
DavidCrow wrote: If the computer that will eventually receive this data is expecting A and I send it (a larger) B, those extra bytes will cause all sorts of data loss due to everything being shifted.
Hi David,
If you have to get it working then it has to be like this. This is the proper way.
<marquee direction="up" height="30" scrolldelay="1" step="1" scrollamount="1" hspace="0" vspace="0">
--Owner Drawn
--Nothing special
--Defeat is temporary but surrender is permanent
--Never say quits
--Jesus is Lord
|
|
|
|
|
Owner drawn wrote: If you have to get it working then it has to be like this. This is the proper way.
I disagree. Your suggestion is not a solution to my problem.
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
One way:
- Derive B from A and add text, from.
- Define an Attrib class:
class Attrib {
CString Name;
CString Value;
};
- Define virtual bool Mod( Attrib *AL, ulong NBR ); in A, override in B.
Where you pass an array of attribs to modify.
- Then:
A a;
B b;
Attrib at[4];
A *p = (some_condition) ? &a : &b;
p->Mod(at, 4);
A::Mod() will only look for/understand r, q attributes and ignore t, f
B::Mod() will only look for/understand r, q, t, f
C::Mod() (in the future) will only ...
...cmk
Save the whales - collect the whole set
|
|
|
|
|
I'm wanting use a VC++ DLL and call a function to it in VC++. The only info I have about the function or the DLL is some VB.NET code that I pulled from a sample app. Here is the code from the sample VB.NET app:
/* VB.NET CODE */
Declare Auto Function GetAllData Lib "RANDOMNAME.dll" _
( _
ByRef bstrDATA1 As String, _
ByRef bstrDATA2 As String, _
ByRef bstrDATA3 As String, _
ByRef bstrDATA4 As String, _
ByRef bstrDATA5 As String, _
ByRef lDATA6 As Int16, _
ByRef bstrDATA7 As String _
) As Int16
/* END VB.NET CODE */
I've made an attempt to convert things over to VC++ but have had no luck. The app compiles just fine but when I call the DLL's function the app crashes. Here is the code I've converted:
/* VC++ CODE */
void CTesterDlg::OnBtnDowork()
{
/* get handle to dll */
HINSTANCE hGetProcIDDLL = LoadLibrary("\\RANDOMNAME.dll");
/* get pointer to the function in the dll*/
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE(hGetProcIDDLL), "GetAllData");
/* Define the Function in the DLL for reuse. This is just prototyping
the dll's function. A mock of it. Use "stdcall" for maximum compatibility.*/
typedef int (__stdcall * pICFUNC)(BSTR,BSTR,BSTR,BSTR,BSTR,int,BSTR);
BSTR bstrDATA1=NULL,bstrDATA2=NULL,bstrDATA3=NULL,bstrDATA4=NULL,bstrDATA5=NULL,bstrDATA7=NULL;
int lDATA6;
pICFUNC GetAllData;
GetAllData= pICFUNC(lpfnGetProcessID);
/* The actual call to the function contained in the dll */
int intMyReturnVal = GetAllData(bstrDATA1,bstrDATA2,bstrDATA3,bstrDATA4,bstrDATA5,lDATA6,bstrDATA7);
/* Release the Dll */
FreeLibrary(hGetProcIDDLL);
}
/* END VC++ CODE */
This is my first real try at using external DLL's so go easy on me! I know that there are many other things that could be causing this app to crash. The Application Error that I'm gettings is:
The instruction at "0x00000000" referenced memory at "0x00000000". The memeory could not be "read".
What I'm really looking for is confirmation of my code. ...does it look right? ...am I missing something simple? Thanks to everyone in advance for all your help!
|
|
|
|
|
Hello.
For one, the VB code says "Int16", and you use int as a substitution.
An int is 32 bits (4 bytes) long. That could be the reason for the crash.
Declare lDATA6 and intMyReturnVal as short int instead.
A short int is 16 bits (in VC6 anyway).
Kakan
|
|
|
|
|
I have a few properties and a function set as a web method ....
When I very the information in my browser I only get the description of the function.... the properties don't even show... however it did before when I used VS.net2003 (I'm using VS.net05 final now)
-Steven Hicks
CPACodeProjectAddict
|
|
|
|
|
I'm a veteren developer who is still trying to get his brain to absorb all of mfc before .net becomes obsolete Anyway, I've read and studied John's excellent article, but there are some issues that make me go hmmm :
I understand WHY you don't do UI stuff in the worker threads, but I have a situation where I work that we seem to defy that logic. The application is a simple SDI which mainly uses its view to display dialog data. When the user presses the "make it so" button, a worker thread is launched that does all of the long work. Part of the information that is passed to this worker thread is a global to the view object. When the worker thread wishes to update the UI with status info, it simply:
pView->WhateverItNeedsToDo(arguments);
and the display is updated. Now, this just seems wrong to me.
The view should be owned by the main application thread - a UI thread - accessing the object just seems like the end of the world should occur.
But it works. Is the application just lucky?
C. Gilley
Will program for food...
My son's PDA is an M249 SAW.
-- modified at 12:45 Thursday 17th November, 2005
|
|
|
|
|
CharlieG wrote: I understand WHY you don't do UI stuff in the worker threads, but I have a situation where I work that we seem to defy that logic.
Does it actually work or does it just appear to work?
CharlieG wrote: The view should be owned by the main application thread - a UI thread - accessing the object just seems like the end of the world should occur.
I believe the operative word is could.
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
David,
In this case, yes . It appears to and does work - basically, we update a progress bar when this happens.
Could/should - true. Your comment seems to imply we got lucky.
C. Gilley
Will program for food...
My son's PDA is an M249 SAW.
|
|
|
|
|
As long as you don't rely on the one-to-one map of HWND and CWnd objects...
My blogs:
http://blog.joycode.com/jiangsheng
http://blog.csdn.net/jiangsheng
http://bloglines.com/public/jiangsheng
Command what is yours
Conquer what is not
---Kane
|
|
|
|
|
Sheng,
I'm not that deep in Windows yet - can you elaborate?
C. Gilley
Will program for food...
My son's PDA is an M249 SAW.
|
|
|
|
|
MFC maintains a 1-1 map between handles and objects that is local to each thread, and some functions, such as CWnd::AssertValid and CWnd::GetParentFrame, acturally rely on an assumption that it is not called from another thread, so the object can be retrived from the map by looking for the handle.
ref.
thread states in MSDN TN058
MTMDI: Demonstrates an MFC User Interface Thread (Visual C++ Samples)
http://www.mvps.org/vcfaq/mfc/11.htm[^]
My blogs:
http://blog.joycode.com/jiangsheng
http://blog.csdn.net/jiangsheng
http://bloglines.com/public/jiangsheng
Command what is yours
Conquer what is not
---Kane
|
|
|
|
|
Hi,
I'm programming a library. It must be thread-safe, so I've a global critical section variable to synchronize the calls among the different calling threads. I also want to offer the possibility to link it against the client as a static library or as a dynamic library. The problem is that InitializeCriticalSection doesn't support multi-threading, in the sense that if it's called from more than one thread with the same CRITICAL_SECTION object, it's result it's undefined. There's no problem in the case that the client is linking with the dynamic library, because I know that DllMain is called just by one thread.
The problem is that, in case it's linked as a static library, I'm forced to 1) write an init() function that should be called by the client (only once) to initialize the critical section: the problem is that the client could forget to call it...or could call it from more than one thread simultaniously (and I can't protect init() since I don't have any critical sections yet) 2) create a static object that in its constructor it initializes the critical section: according to the c++ standard we don't know what will be the static object initialization order amongst different modules...so I can receive a call from the client before initializing the critical section...
If anybody has any suggestion, please let me know
Thanks,
Federico
|
|
|
|
|
Federico Milano wrote: the problem is that the client could forget to call it
So could all of your functions test for this, and return a "you need to call init first" error message? I don't see that as a problem. There's loads of Windows API calls where you need to call Function1 before you can validly call Function2.
Federico Milano wrote: or could call it from more than one thread simultaniously
Are you saying that you'll get two, simultaneous calls to DllMain with a dwReason of DLL_PROCESS_ATTACH?
|
|
|
|
|
Graham Bradshaw wrote: Are you saying that you'll get two, simultaneous calls to DllMain with a dwReason of DLL_PROCESS_ATTACH?
No, I'm saying that if you need a client to call init(), init() could be called from multiple threads simultaneously. You can't enforce this by soft, I think.
I know that DllMain is called only once with a dwReason of DLL_PROCESS_ATTACH for a process that loads that dll, but what if I want to link my library statically? DllMain will not be called and I can't use static objects (because of initialization order issues) and the init() method is unsafe, what should I do?
Of course I can solve this with the DllMain thing, not linking statically, but I wanted something more OS independent...
Thanks,
Federico
|
|
|
|
|
Don't allow the client to call your software during image load and use a RAII static critical section. This can be a verbal contract that isn't enforced in software.
Having things happen during image load is a really bad idea and leads to the types of problems you are having to deal with. If you just have to have things happen on image load via constructors, the constructors should never refrence another C++ object and only reference POD objects.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
This might be a dumb question, but would a static local (not member) variable in the init() function work? It would be initialzed to zero at first entry into the function, and you could check/increment the value using InterlockedCompareExchange() to see if initialization has taken place or not. You could use two variables, one to enter initialization of the Critical Section, and another to indicate that the CS was initialized. That might prevent two threads from racing on initialization of the CS and entering it - if one thread fails the first InterlockedCompareExchange() call, the second would confirm that the CS is initialized and ready for use.
I am not certain, but I think that initialization of a function-local static variable is thread-safe. But I could be wrong. Either way, the use of InterlockedCompareExchange() is thread-safe and that might work for you.
Peace!
-=- James If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Tip for new SUV drivers: Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! DeleteFXPFiles & CheckFavorites (Please rate this post!)
|
|
|
|
|
Hi all,
After using the navigate method to open a webpage, i want to lock the content of the webpage (user can't do anything in the view like right mouse clicking, copying text...) just can scroll the web page. I tried using the EnableWindow method but it disabled both the view and the scroll bar ( i don't want disable the scrollbar). Do you have any solution for this case ?
thanks,
Ken
|
|
|
|
|
You can IThumbnailCapture to capture a snapshot...
My blogs:
http://blog.joycode.com/jiangsheng
http://blog.csdn.net/jiangsheng
http://bloglines.com/public/jiangsheng
Command what is yours
Conquer what is not
---Kane
|
|
|
|