|
It may count as advanced at this stage of learning (getting arrays and pointers in your head is very handy!), but there are classes that encapsulate strings, and you can then use +
eg:
std::string one = "hello";
std::string one = "world";
somefunc (one + two);
Also look at CString if you're using MFC.
Iain.
|
|
|
|
|
visual 2005 sp1
the code in debug mode
s is a SOCKET value and set in unblock mode
pbuff is a char * pointer
isize is a int value , is the buff size of pbuff , about 6440
int i=recv(s,pbuff, isize , 0);
if(i==SOCKET_ERROR) //<--here is right
{
iierror=WSAGetLastError( );
if(iierror!=WSAEWOULDBLOCK) // if it is not a block error
{
return -1;
}
else retur 0 ; // need block and recv again
}
//--------------------------------------------------------
the code can run no error in release mode , and if the client send data immediately ,
it is ok , but if data no coming ,
the iierror value is 2, not wsaewouldblock , why?
refer to MSDN, the SOCKET error return more than 10000 ,
and I suppos it is a error of win api parameters, but when the data arrive in no time ,
the function runs ok , that means all parameters is ok ,
who knows why? and how to do with it?
should I replace with if(iierror!=2 || iierror!=WSAEWOULDBLOCK) return -1;
Thank you
Hello,
pleasure to meet you.
|
|
|
|
|
And if in release mode
the WSAGetLastError( ) will return the right value of WSAEWOULDBLOCK
never return 2
the code runs well in release mode, but why return 2 in debug mode?
Hello,
pleasure to meet you.
|
|
|
|
|
That doesn't make sense (as you know).
How are you checking the WSAGetLastError() return value in release mode?
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
How are you checking the WSAGetLastError() return value in release mode?
It is simple to use ::OutputDebugString( ) or use my only calss qtlog , to record it to disk file or just send it by outputdebugstring to any windows debuger , use visual studio debug ->attach process , I can catch it .
But I really want to know why return 2 ? It seems just a bug of winsock .
Hello,
pleasure to meet you.
|
|
|
|
|
danscort yu wrote: But I really want to know why return 2 ?
It shouldn't.
What does the code look like that creates the debug string?
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
OK,
I think I got the reason
Because I reset socket receive buffer size in my program
and in debug mode , system will not alloc system buffer for the socket if no data arrive
so it may return value 2 means file not ready or exist
If the data already arrive , even one and only one byte , system will alloc the buffer size as I reset , and then it will go well
In release mode , buffer will immediately alloc after reset buffer size of socket , so it will go well.
I just think it is a bug fo winsock in reset buffer size .
Hello,
pleasure to meet you.
|
|
|
|
|
danscort yu wrote: I reset socket receive buffer size
How are you doing that? Using what function(s)?
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
The function pointer tutorials have a good example of passing a global function pointer as an argument and it's laid out in the following manner:
int DoIt(float x, char y, char z)
{
return 0;
}
void PassPtr(int (*pt2Func)(float, char, char))
{
int result = (*pt2Func)(12, 'a', 'b');
}
void Pass_A_Function_Pointer()
{
PassPtr(&DoIt);
}
My scenario is a bit different though. It's something more like:
int Class::DoIt(float x, char y, char z)
{
return 0;
}
void PassPtr(int (*pt2Func)(float, char, char))
{
int result = (*pt2Func)(12, 'a', 'b');
}
If I do the same as in the first instance and call PassPtr(&DoIt), it won't compile, giving me the following error when declaring the function pointer:
error C2276: '&' : illegal operation on bound member function expression
If I change the call to PassPtr(&Class::DoIt), it won't compile, giving me the following error when trying to pass the function pointer:
error C2664: <snip> cannot convert parameter 1 from 'int (__thiscall Class::* )(float, char, char)' to 'int (__cdecl *)(float, char, char)'
Some names have been changed, but this is pretty much what's going wrong. Does anyone know how to solve this issue? It would seem like I need to declare just a global function instead of actually passing a class member function.
|
|
|
|
|
|
|
Nemanjas link shows why you can't call member functions like this.
If declaring the method static isn't what you need (maybe your DoIt() method needs to access
non-static members of the class, for instance), it IS possible to call a member function through
a pointer, but as with all non-static class members, an object of that class is required.
The syntax is a little crazy but it's consistent with function pointers...
int Class::DoIt(float x, char y, char z)
{
return 0;
}
...
typedef int (Class::*ClassDoItPtr)(float, char, char);
...
void PassPtr(ClassDoItPtr pt2Func)
{
Class classobject();
int result = (classobject.*pt2Func)(12, 'a', 'b');
}
Hopefully I got that right
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Hmm... I'm looking at this example, and the typedef is quite messy, however I assume it means you're typedefing the function pointer to something called ClassDoItPtr. Then, you initialize the ClassDoItPtr - so far so good.
The problem I have with this is that you have to create a whole new object of type Class, otherwise, it would look like a very good, easy solution.
Give me some time to ponder this issue -- I've got an implementation idea.
|
|
|
|
|
Yeah, the typedef just makes an alias for the function pointer type so you can use one word
instead of an entire function prototype. That's why you could declare your PassPtr() function
either of the ways I showed.
I've been trying to think of an example where this is useful but I can't! LOL Google shows some
ideas but I can't imagine a real-world example of why I'd need to use member pointers unless
I needed to mess with polymorphism at runtime.
Regardless, it's probably useless for your needs - I just wanted to point out that it could be
done Like you mentioned, needing an entire object just to make the call through a pointer
makes the whole thing kinda overkill.
If you're interested, I googled "member function pointers" for reasons why I might want to use
them. Now my head hurts - C++ overload
Cheers!
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
What about using the existing this pointer in order to make the function call? I'm trying to implement a class that will do that, right now.
The reason why I want to do this is for a generic function caller.
All I have to do is call Process(somefunction) and it will process the function (by using one of the threads in my self-implemented ThreadPool class). I made a post earlier, with a stripped down version of it, to see if I could garner any design comments, but no one replied to that post.
MODIFIED:
Actually, I had another question about your implementation, Mark. You first create the function pointer from the existing this object. Then you create a new object of the same type as this, and you try to call the function pointer from the newly created object. Are you sure that works? Wouldn't you have to create the new object first?
|
|
|
|
|
Is PassPtr() actually Class::PassPtr()? If so, then yes, you can call through the this pointer
and eliminate the need to create a separate object.
I think this is the syntax:
void Class::PassPtr(int (Class::*pt2Func)(float, char, char))
{
int result = (this->*pt2Func)(12, 'a', 'b');
}
Cyrilix wrote: You first create the function pointer from the existing this object. Then you create a new
object of the same type as this, and you try to call the function pointer from the newly created
object. Are you sure that works? Wouldn't you have to create the new object first?
Working from your sample code, I didn't have the full implementation of "Class" so I just showed
an object (classobject) created with a default constructor: "Class classobject();"
Yes you'd want to (actually you'd need to) properly construct a Class object.
I did that because you didn't show PassPtr() as a member of Class, but if it is a member, see
above...
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Hi,
I'm trying to figure out how I can set registry key permissions in C++ so that I can then delete them using RegDeleteKey() (and not get the Access is denied error code).
Does anyone know how to do this?
Thanks!
KR
|
|
|
|
|
I've been trying to change the registry key permissions by using the access control list, but I still have some questions:
So I'm able to get as far as getting the ACL for one of my registry keys, and iterating through the ACE's of that ACL. But my problem is, how can I tell which ACEs have which permissions set? I want to find any that have the Delete permission denied, and remove those from the list (using DeleteAce()) but I don't know how to tell which ACEs have Delete denied for any users.
int FindAceIndexToDelete(PACL pACL)<br />
{<br />
int i = 0;<br />
PVOID pTempAce;<br />
int i = 0;<br />
<br />
while (1) {<br />
if (!GetAce(pACL, i, &pTempAce))<br />
break;<br />
<br />
i++;<br />
}<br />
}
KR
|
|
|
|
|
Nevermind, I got it.
GetNamedSecurityInfo on the key, GetAce on the ACL, find the ACE with header type = ACCESS_DENIED_ACE_TYPE, DeleteAce on all of those, then SetNamedSecurityInfo to set the new stuff.
KR
|
|
|
|
|
Hi all. Im trying to make a some what secret question program but im failing over and over. Its pretty simple and i thought i could create something pretty simple. What its supposed to do is ask what the secret question is and if the answer is provided then it would inform the user. And if if not then then again, it would inform the user. Here's my code:
<br />
#include <iostream><br />
using namespace std;<br />
<br />
<br />
<br />
int main()<br />
{<br />
const int MAX_SIZE=100;<br />
char hiddenword[MAX_SIZE]="secret"; <br />
printf("Type the word: ");<br />
cin.getline(hiddenword, MAX_SIZE);<br />
if(!hiddenword){<br />
printf("That is a incorrect word...try again\n");<br />
}<br />
else{<br />
printf("Congradulations! You figured out the secret word!\n");<br />
}<br />
system("pause");<br />
return 0;<br />
}<br />
No matter how many ways i move it around and around it does'nt achieve the desired functionality. Any suggestions?? Thanx in advance!
|
|
|
|
|
You're overwriting hiddenword when you call the cin.getline() function, among other problems.
What you need to do is get the arg in a separate char array and compare that to hiddenword using strcmp or something similar.
This is how I would do it:
int main()<br />
{<br />
const int MAX_SIZE=100;<br />
char hiddenword[MAX_SIZE]; <br />
char typedword[MAX_SIZE];<br />
sprintf(hiddenword, "secret");<br />
printf("Type the word: ");<br />
cin.getline(typedword, MAX_SIZE);<br />
if(strcmp(hiddenword, typedword)){
printf("That is an incorrect word...try again\n");<br />
}<br />
else{<br />
printf("Congratulations! You figured out the secret word!\n");<br />
}<br />
system("pause");<br />
return 0;<br />
}
KR
|
|
|
|
|
As an aside, you're not using C, because you use cin. I'd recommend moving all this code to use C++, for example, using cout instead of printf, and std::string instead of char arrays.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
When I run a module using ShellExecuteEx() i get access to two Handles, a hInstance and a hProcess. How can I use either at a later stage to determine whether the module is still running, How can I use either to kill the instance of the module that ShellExecuteEx() started.
Regards
LateNightsInNewry
|
|
|
|
|
If you want to kill the process, look at this article here.
I'm not sure about how to determine whether the module is running :s sorry
Hope this helps!
--PerspX
|
|
|
|
|
LateNightsInNewry wrote: How can I use either at a later stage to determine whether the module is still running,
The hProcess member (assuming you've used the SEE_MASK_NOCLOSEPROCESS flag) of SHELLEXECUTEINFO
can be used in a synchronization wait function - it will be signaled when the process terminates.
// polling method - wait timeout is 0
if (WAIT_OBJECT_0 == ::WaitForSingleObject(ShellExecuteInfo.hProcess, 0))
{
//process has ended
}
A process should be allowed to terminate normally. If you absolutely must terminate it from
another process you can use TerminateProcess with the same handle as above. Remember you
don't know the state of the other process when you do this so data loss can occur. It's
much better to get the other process to terminate itself normally if at all possible.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|