When i send to client a string (tkString), client tells me (inside WMClientRecv) access violation when trying to rebuild TValue, why ? -_-" with other typed data it works well...
for example, Integer (tkEnum)
here's server code (sends invoke data to client)
procedure TServerClass.InvokeMethod(const InvokableMethod: TInvokeableMethod; const MethodArg: TValue);
var
InvokeRec : packed record
Method: Array[0..19] of Char;
ArgRawSize: Integer;
ArgTypeInf: TTypeInfo;
ArgRawData: Array[0..255] of Byte;
end;
begin
// copy method name to record
lstrcpy(InvokeRec.Method, PChar(InvokableMethod));
// copy arg array to record
InvokeRec.ArgRawSize := MethodArg.DataSize;
if (MethodArg.DataSize <> 0) then
begin
MethodArg.ExtractRawData(PByte(@InvokeRec.ArgRawData[0]));
InvokeRec.ArgTypeInf := MethodArg.TypeInfo^;
end;
// send record
ServerSocket.Socket.Connections[idxSocket].SendBuf(PByte(@InvokeRec)^, SizeOf(InvokeRec));
end;
Client reads it as:
procedure TClientClass.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
var
Buffer: PByte;
BufLen: Integer;
InvokeRec: TInvokeRec;
begin
BufLen := Socket.ReceiveLength;
Memo1.Lines.Append(Format('%d: Received %d bytes', [Memo1.Lines.Count, BufLen]));
// dump keep-alive from recv buffer
if (BufLen = 64) then
begin
GetMem(Buffer, BufLen);
try
Socket.ReceiveBuf(Buffer^, BufLen);
finally
FreeMem(Buffer, BufLen);
end;
Exit;
end;
Socket.ReceiveBuf(PByte(@InvokeRec)^, BufLen);
SendMessage(Handle, WM_ClientRecv, 0, LPARAM(@InvokeRec));
end;
Routine of WMClientRecv:
procedure TClientClass.WMClientRecv(var Msg: TMessage);
var
// we send to server
ReadRec: TSharedRec;
// we recv from server
InvokeRecPtr: PInvokeRec;
Value: TValue;
begin
InvokeRecPtr := PInvokeRec(Msg.LParam);
case InvokeRecPtr.ArgRawSize of
0:
Value.Empty;
else
TValue.Make(PByte(@InvokeRecPtr.ArgRawData)^, PTypeInfo(@InvokeRecPtr.ArgTypeInf), Value);
end;
InvokableSubclass.ExecMethod(InvokeRecPtr.Method, Value);
end;
And ExceMethod:
procedure TInvokableSubclass.ExecMethod(const vmName: string; const Arg0: TValue);
var
LContext: TRttiContext;
begin
//
FSendMode := TextMode;
//
if (Arg0.DataSize = 0) then
begin
LContext.GetType(TInvokableSubclass).GetMethod(vmName).Invoke(Self, []);
Exit;
end;
LContext.GetType(TInvokableSubclass).GetMethod(vmName).Invoke(Self, Arg0);
end;