Увеличение указателя не компилируется так, как я планировал - PullRequest
1 голос
/ 21 июля 2009

Я пытался сделать свой код максимально простым, но мне это не удалось.

Это мой код:

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;

Ошибка помещена в

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

Ошибка: «Постоянный объект не может быть передан как параметр var»

Я понимаю, что мне нужна переменная, но нет ли способа сделать это без добавления еще одной строки?

Ответы [ 3 ]

5 голосов
/ 21 июля 2009

Когда компилятор жалуется на то, как вы передаете параметр, первое, что вам нужно знать, это то, что ожидает параметр. Поэтому вам стоит взглянуть на объявление Send. Если просмотр декларации не сразу дает вам представление о том, что нужно исправить, вам нужно включить эту декларацию в код, который вы публикуете в своем вопросе.

Я подозреваю , что это на самом деле не имеет ничего общего с увеличением указателя. Вместо этого компилятор жалуется на третий параметр, где вы пытаетесь передать выражение size-dwError. Я думаю, что параметр объявлен так:

var buffersize: Word;

Функция планирует предоставить новое значение для этого параметра - это то, что означает var, поэтому то, что вы передаете этому параметру, должно быть чем-то, что может получить значение. Вы не можете присвоить новое значение результату вычитания двух переменных.

Посмотрите, где компилятор пожаловался на эту строку. Разве он не поместил курсор где-то рядом с третьим параметром? Это подсказка, что проблема есть.

Уменьшить size, а затем передать его функции.

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

Почему вы хотите добавить еще одну строку? Вы достигли своей квоты на этот день? Линии дешевы; не бойтесь использовать два, чтобы выразить себя, когда один не будет делать. Аналогично для переменных. Когда ваш код не работает, сохранение байта или двух вообще не имеет значения.

По крайней мере, вы должны были добавить больше строк, чтобы отследить источник проблемы. Если у вас есть одна строка кода, которая выполняет несколько независимых вычислений (например, получение нового значения указателя, получение нового размера и вызов функции), разбейте строку на несколько отдельных частей. Таким образом, если с одним из них возникнет проблема, и компилятор пожалуется, вы точно будете знать, какой из них виноват.

4 голосов
/ 21 июля 2009

Правильно, это не будет работать так, как написано. Когда вы имеете дело с параметрами var, вы должны создать параметр ДО того, как передать его процедуре / функции. Когда передается параметр Var, процедуре разрешается его изменять. Если бы вы попытались скопировать две переменные вместе в вызове, куда бы вы пошли?

Другая проблема заключается в том, что dwError не сбрасывается. Метод класса НЕ имеет доступа к элементам данных объекта, который определяет класс. Если вы отбросите класс, у вас будет доступ к элементам данных, но для этого потребуется сначала создать класс.

Вы должны использовать методы класса только в тех местах, где ввод и вывод полностью содержатся в методе.

Как вы распределяете свой буфер? Внутренне это массив?

0 голосов
/ 21 июля 2009

Похоже, что Send имеет параметр формата (например, send (const что-то; size: integer)

Обходной путь использует pchar (fullpointerexpress) [0]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...