|
close. but lower_bound doesn't really do a search. it just tells you where you could insert a new item. or, from MSDN: "[lower_bound] determines the lowest position before which val can be inserted in the sequence and still preserve its ordering".
i really need it to return the item i'm searching for, not the next-lowest value.
-c
There's one easy way to prove the effectiveness of 'letting the market decide' when it comes to environmental protection. It's spelt 'S-U-V'.
--Holgate, from Plastic
|
|
|
|
|
Chris Losinger wrote:
but lower_bound doesn't really do a search.
That's right but I was thinking you could check the *next* element to see if it's the one you want.
note to self: but this doesn't work if the item is not present!
[edit] hmmm... may it does. doesn't matter - equal_range() seems to be the ticket anyway.
Isn't equal_range() exactly what you want anyway? A quick test seems to show that it returns (x,x+1) if you're looking for x and find it or (end,end) if it's not present.
he he he. I like it in the kitchen! - Marc Clifton (on being flamed)
Awasu[^]: A free RSS reader with support for Code Project.
|
|
|
|
|
nope. equal_range is just like lower_bound, but with a span, instead of a single position:
"the function determines the largest range of positions over which val can be inserted in the sequence and still preserve its ordering"
my vector has X elements. each element has an integer member variable that i'm ordering, and searching by. the less than operator for these elements only looks at the ordering and searching integer, nothing else. in the case i'm testing, these values range from 10 to 170.
if i do an equal_range "search" (or lower_bound) for "0", i get an iterator for the first element in the sequence, the one that contains "10".
i suppose i can test that iterator to see if the element is actually the one i'm searching for. but it seems like a huge hole in the STL, to not provide a binary search on a sorted collection.
oh well. guess i'll write my own.
-c
There's one easy way to prove the effectiveness of 'letting the market decide' when it comes to environmental protection. It's spelt 'S-U-V'.
--Holgate, from Plastic
|
|
|
|
|
Then MSDN is misleading. ForwardIterator lower_bound(ForwardIterator beg, ForwardIterator end, const T& value, BinaryPredicate op) returns the position of the first element with value equal or greater than value . Just add a comparision and you have the search function you need.
|
|
|
|
|
yeah, that's basically what i ended up doing; i combined the lower_bound code with the equality test into a new function, and named it appropriately: "vector_binary_search".
-c
There's one easy way to prove the effectiveness of 'letting the market decide' when it comes to environmental protection. It's spelt 'S-U-V'.
--Holgate, from Plastic
|
|
|
|
|
Chris Losinger wrote:
please don't say "binary_search"
How about bin_search? This should return the position in the vector if that is any better?
int bin_search(vector<char>&A, char key)
{
int left = 0;
int right = A.size() - 1;
while(left < right)
{
int mid = (left + right)/2;
if(A[mid] == key) return mid;
else if(A[mid] < key)
left = mid + 1;
else
right = mid + 1;
}
return A.size();
}
Nick Parker
Not everything that can be counted counts, and not everything that counts can be counted. - Albert Einstein
|
|
|
|
|
close. but it needs to take a predicate, because the elements in the vector are classes and i'm looking an element which has a member variable equal to a certain value.
right now, my code looks like:
class scaneql
{
public:
scaneql( int lookfor) : i(lookfor) {}
bool operator()(const scan & a) const
{
return a.i == i;
}
private:
int i;
};
...
std::vector< scan>::const_iterator curScan = std::find_if(m_rows.begin(), m_rows.end(), scaneql((int)y));
There's one easy way to prove the effectiveness of 'letting the market decide' when it comes to environmental protection. It's spelt 'S-U-V'.
--Holgate, from Plastic
|
|
|
|
|
Are you going to use this predicate in more than one spot? Do you need to search for member variables? If this is a one shot deal, just hack up bin_search and be done with it.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Is a binary search faster than using find_if? Is that the reason you are looking for something else?
Todd Smith
|
|
|
|
|
yep. find_if just iterates over all items till it finds one that matches. this is fine, if your collection isn't sorted. but if it is sorted, a binary search is much much faster.
-c
There's one easy way to prove the effectiveness of 'letting the market decide' when it comes to environmental protection. It's spelt 'S-U-V'.
--Holgate, from Plastic
|
|
|
|
|
I am programming with ATL 3.0, building an application where I need a main exe server, launching multiple exe server instances (of the same exe) through CoGetObject... To be clearer, I need to have server1.exe and multiple server2.exe process loaded, one for each COM component that is started through CoGetObject.
Is there a way to do this? The code generated automatically creates me only one server2.exe process where all the instances of my COM component are hosted. I read articles about people having problems getting a single instance, but me, I'd like to do the exact contrary!
|
|
|
|
|
When server starts, he registers own class objects at such manner:
hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,REGCLS_MULTIPLEUSE);
You can change REGCLS_MULTIPLEUSE constant with REGCLS_SINGLEUSE to make one object instance per one server process.
With best wishes,
Vita
|
|
|
|
|
Hello,
I have developed an Activex control with VS.NET C++ using ATL 7.0. This control contains two properties, four events and two methods. It works satisfactorily on Activex test container
But, in VB.NET When I put my control on the form, 1. it takes much time to display(Though it doesn't contain any drawing code) 2. VB's properties window displays my control's properties successfully for the first time(Though it displays property's value as junk), but after running test project, and coming back to vb's form containing my control and when I try to see property's value, I can see only one property only.
My other property's name simply vanishes from the list of properties.
What could be wrong. What shall I check. How do I correct it.
Tushar Bhatt
|
|
|
|
|
Hello,
here's my Problem:
if I use the "old" filestreams declared in fstream.h, I get an "Old IOStreams Deprecated" warning. I'd like to use the new ones from the "fstream"-header, but cannot find how to set the old protection flag or something similiar. I need that to keep the file readable from other Applications in some cases.
I also need to prevent reading by other Applications in other cases (e.g. Virusscaners), so the old possibility of sharing or protecting external access is needed.
thanks for your answers.
Klaus
|
|
|
|
|
I have an excellent reference on iostreams at home, if you can provide a further explantion of the old syntax that is missing, and what it does, I'd be happy to have a look for you.
Conversely, people wrote code using the old iostreams, is there any reason beyond the warning that you're loathe to do the same ?
Christian
No offense, but I don't really want to encourage the creation of another VB developer. - Larry Antram 22 Oct 2002
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
Again, you can screw up a C/C++ program just as easily as a VB program. OK, maybe not as easily, but it's certainly doable. - Jamie Nordmeyer - 15-Nov-2002
|
|
|
|
|
Here the exacter description:
One of the old syntax fstream Constructors:
fstream (const char* szName, int nMode, int nProt = filebuf::openprot )
with nMode e.g.
ios::in for reading files,
ios::out for writing files.
and nProt e.g.
filebuf::sh_none Exclusive mode — no sharing,
filebuf::sh_read Read sharing allowed.
the new fstream classes simply don't support the "nProt"-Flag in any constructor (as far as 'I know).
I'd like to rework my code in terms of the new streams to be able to use it with future Compiler-Versions. I heard with the next .Net's Update old fstreams may no longer be suported.
Moreover my Emloyer wants me to change it.
|
|
|
|
|
I'm afraid that my reference does not even mention this sort of protection mode. The basic_filebuf object still exists though, but openprot does not exist within it.
I'd suggest that your only real option is to create your own streaming class that is derived from iostreams and provides the functionality you're looking for. I have some articles here on CP that would help.
Christian
No offense, but I don't really want to encourage the creation of another VB developer. - Larry Antram 22 Oct 2002
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
Again, you can screw up a C/C++ program just as easily as a VB program. OK, maybe not as easily, but it's certainly doable. - Jamie Nordmeyer - 15-Nov-2002
|
|
|
|
|
I had this same problem ages ago. IIRC, these old flags were a Microsoft-specific thing and were dropped because they're not part of the standard (!)
I'd wear a miniskirt and pimp myself for an extra ten grand a year. - David Wulff
Awasu[^]: A free RSS reader with support for Code Project.
|
|
|
|
|
In a full control, how can I do something like HINSTANCE hInst = _Module.GetModuleInstance() with ATL 7? I know CComModule is replaced, but can't find related info. TIA.
|
|
|
|
|
try this:
<br />
_AtlBaseModule.GetModuleInstance();<br />
not tested it, but it should work (based on help, also succesfull compilation). Problem is that _AtlBaseModule is somehow missed in my Intelisense
Hope this helps
|
|
|
|
|
hi,
I've developed one ATL EXE server com. This server contains 2 threads.
The main thread (lets call it T1) will do following tasks:
1. Create second thread ( and this I think should be called T2) using "CoMarshalInterThreadInterfaceInStream".
2. Receive input from client application:
HRESULT CMainThread::ReceiveClientInput(BSTR AnyValue)<br />
{<br />
<br />
EnterCriticalSection(&cs); <br />
m_isFire = true;<br />
LeaveCriticalSection(&cs);<br />
<br />
return S_OK;<br />
}
T2 on the other hand continously (every 2 seconds) check for m_isFire value and fire the event:
void CSecondThread::CheckFlag(void)<br />
{<br />
<br />
EnterCriticalSection(&cs); <br />
<br />
if (isFire == true ){<br />
Fire_NotifyAllConnectedClients();<br />
isFire = false;<br />
}<br />
<br />
LeaveCriticalSection(&cs);<br />
<br />
}
Now, when event fired from above COM method, there is no client receive this event
I guess I've missed something in my code since I'm quite new in using VC++.
Thank u very very much in advance . Any advice, help and suggestions strongly aprreciated.
Regards,
newbie
|
|
|
|
|
Have not a clue what it can be from this small excerpt, maybe, you can check, if you initialize the COM in your thread (first thing usually forgoten) on the beginning of your second thread - say CoInitializeEx(...); as a first method of the threadproc and CoUninitialize() as a last one.
Next thingie - the fact that in the second function you checking isFire instead of m_isFire I consider as a typo, but...
Another thing, yes, the interface should be marshalled through CoMarshal... but check carefully what pointer you are using in the Fire_NotifyAllConnectedClients - the pointers you are using there should be unmarshalled (opposite function to CoMarshal...) before you will use them.
I do not work much with exe servers, so I can give you only these 'universal' tips, but maybe it will help you. Don't hesitate to contact me if necessary or need more explanation
|
|
|
|
|
hi, thankx a lot for ur reply !
For ur info I've used a comarshal :
STDMETHODIMP CIBMSSchedule::ExplicitInitialize()<br />
{<br />
HRESULT hr =::CoMarshalInterThreadInterfaceInStream(IID_IInternalExec, static_cast<IInternalExec*>(this), &m_pStream);<br />
<br />
if (FAILED(hr))<br />
{<br />
MessageBox(NULL,"Could not CoMarshal", "CCom control", MB_OK | MB_ICONERROR);<br />
}<br />
<br />
StartThread();<br />
<br />
return S_OK;<br />
}<br />
<br />
void CIBMSSchedule::PreCommand()<br />
{<br />
<br />
HRESULT hr = CoInitialize(NULL);<br />
if (FAILED(hr))<br />
::MessageBox(NULL,"Bad Carma","ReceiveThread",MB_OK);<br />
if (FAILED(::CoGetInterfaceAndReleaseStream(m_pStream, IID_IInternalExec, (void**)&m_pIInternalExec)))<br />
{<br />
::MessageBox(NULL,"Bad Carma, CoGetInterfaceAndReleaseStream","ReceiveThread",MB_OK);<br />
}<br />
}
ExplicitInitialize() called by clients at client's initializion process; and PreCommand() called when this application is about to send event to every connected clients.
And by the way Im not understand what u mean by "the pointers you are using there should be unmarshalled"; however below is the code for Fire_NotifyAllConnectedClients :
VOID Fire_OnReceiveSchedule(BSTR str)<br />
{<br />
T* pT = static_cast<T*>(this);<br />
int nConnectionIndex;<br />
CComVariant* pvars = new CComVariant[1];<br />
int nConnections = m_vec.GetSize();<br />
<br />
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)<br />
{<br />
pT->Lock();<br />
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);<br />
pT->Unlock();<br />
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);<br />
if (pDispatch != NULL)<br />
{<br />
pvars[0] = str;<br />
DISPPARAMS disp = { pvars, NULL, 1, 0 };<br />
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);<br />
}<br />
}<br />
delete[] pvars;<br />
<br />
}
I will email to u the application together with program flow for ur reference. Is it possible to put attachments here ?
Thanx a lot in advance.
Regards,
newbie
|
|
|
|
|
Goood morning there
OK, I think I get it. It wasn't too difficult. But first, what I meant by the "the pointers you are using there should be unmarshalled". I saw a people making code like that:
pseudo
MarshalInterface
start thread
Unmarshal Interface to member m_spCorrect;
use completely another member like m_vec.GetAt directly from the new thread (therefore need marshalling but not used on this pointer).
But this was not your case.
Your problem is hidden in, say unrelated, method CIBMSSchedule::Run. Here you have somewhere about line 111 command Sleep(5000); and this is that one causes your problems. How marshalling works is, very shortly, that if he needs to transfer call from thread A to thread B, (s)he/it uses a old plain window messages. Then all threads in STA (you are using) must have the message pump to work correctly.
Then replace your Sleep(5000) with something like:
<br />
MSG msg;<br />
while( ::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )<br />
{<br />
BOOL bRet = ::GetMessage(&msg, NULL, 0, 0);<br />
<br />
::TranslateMessage(&msg);<br />
::DispatchMessage(&msg);<br />
<br />
}<br />
and then your code started to work for me (Event received at VB client).
Some another notes:
- consider to somehow remove the Sleep design pattern .
- I see that you are adding thread for each client, but didn't see the remove mechanism (might be my fault, didn't check it too carefully )
- hint: I believe (as I don't work with exe components), that for remove this marshalling pains, you can use CoInitializeEx(NULL,COINIT_MULTITHREADED); for free threading. Then it behaves like normal threads and no need for marshaling (only between VB and VC). Then you don't need to carry about, as the _tWinMain already contains the msg pump doing that.
Hope this helps & enjoy
|
|
|
|
|
hi,
thanx geo. U advice is works. But somehow when I run the application it took a lot of CPU (99 %). I think its b'coz of PeekMessage. Is there any replacement for PeekMessage ?
For ur info i've try to change ur code to prevent this problem, but i cant send message to clients.
Thanx a lot geo. U really help me a lot
Regards,
Din Krop
|
|
|
|
|