views:

120

answers:

3

Hello,

I tried to make my code as simple as possible,but I failed at it.

This is my code:

class function TWS.WinsockSend(s:integer;buffer:pointer;size:word):boolean;
begin
  dwError := Send(s,buffer,size,0);
// Debug
  if(dwError = SOCKET_ERROR) then
  begin
    dwError := WSAGetLastError;
    CloseSocket(s);
    WSACleanup;
    case (dwerror) of
      //Case statement
    else
      LogToFile('Unhandled error: ' + IntToStr(dwError) + ' generated by WSASend');
    end;
    Exit(false);
  end;

// if the size of the bytes sent isn't the expected one.
  while(dwError <> size) do
    dwError:= dwError + Send(s,Ptr(cardinal(buffer) + dwError),size-dwError,0);
  Exit(true);
end;

The error is placed at

dwError:= dwError + Send(s,Ptr(cardinal(buffer) + dwError),size-dwError,0);

Error is "Constant object cannot be passed as var parameter"

I understand I need a variable,but isn't there a way I can do it without adding one more line?

+4  A: 

Correct, this will not work as written. When your dealing with var parameters, you have to build the parameter BEFORE passing it to the procedure/function. When a Var parameter is passed, the procedure is allowed to modify it. If you attempted to copy two variables together on the call, where would this result go?

The other issue is that dwError is not delcared. A class method does NOT have access to the data elements of the object the class defines. If you drop the class, then you will have access to the data elements, but will require that the class first be created.

You should only be using class methods in places where the input and output are completely contained within the method.

How are you allocating your buffer? Internally is it an array?

skamradt
+5  A: 

When the compiler complains about the way you're passing a parameter, the first thing you need to know is what the parameter expects. Therefore, you should go look at the declaration of Send. If looking at the declaration doesn't immediately give you an idea of what to fix, then you need to include that declaration with the code you post in your question.

I suspect that this actually has nothing to do with incrementing a pointer. Instead, the compiler is complaining about the third parameter, where you are trying to pass the expression size-dwError. I guess the parameter is declared like this:

var buffersize: Word;

The function plans on providing a new value for that parameter — that's what var means — so the thing you pass to that parameter needs to be something that can receive a value. You can't assign a new value to the result of subtracting two variables.

Take a closer look at where the compiler complained about that line. Didn't it place the cursor somewhere near the third parameter? That's a clue that the problem is there.

Decrement size, and then pass it to the function.

Dec(size, dwError);
Inc(dwError, Send(s, Ptr(cardinal(buffer) + dwError), size, 0));

Why do you care about adding another line? Have you reached your quota for the day? Lines are cheap; don't be afraid to use two to express yourself when one won't do. Likewise for variables. When your code doesn't work, saving a byte or two doesn't matter at all.

At the very least, you should have added more lines in order to track down the source of the problem. When you have one line of code that's performing several independent calculations (such as getting a new pointer value, getting a new size, and calling a function), break the line into several separate pieces. That way, if there's a problem with one of them and the compiler complains, you'll know exactly which one to blame.

Rob Kennedy
You were wrong,the compiler compains about the second parameter,but I upvoted your answer! :)
John
A: 

Sounds like Send has a format parameter (like send (const something;size:integer)

Workaround is using pchar (entirepointerexpression)[0]

Marco van de Voort