Adam Burgoyne wrote:
> Thanks for the explanation and example, Arno, but I was 1 step ahead
> of you in realising the mistake.
> 
> What I did (which appears to have worked as the errors are not being
> reported now) is to simply move the "Note" variable into the global
> scope. 
> 
> The DLL only gets called by one external process so I think it's a
> reasonably safe approach... unless you know different. :-)

The number of processes doesn't matter since each loads its private 
copy of the DLL. However since your exported function seems to be
called by multiple threads of the same host process you may not use
a global variable since that won't be thread-safe.

-- 
Arno Garrels
   

> 
> Regards, Adam
> 
> -----Original Message-----
> From: twsocket-boun...@elists.org
> [mailto:twsocket-boun...@elists.org] On Behalf Of Arno Garrels
> Sent: 16 September 2011 07:17
> To: ICS support mailing
> Subject: Re: [twsocket] DLL implementation advice (or example)...
> 
> Adam Burgoyne wrote:
>> I've now changed the
>> code to this which should solve the problem if I understood
>> correctly: 
>> 
>> function ReadMessage: PAnsiChar; stdcall; var
>>  Note: AnsiString;
>> begin
>>  EnterCriticalSection(CritSectn);
>> 
>>  if (NotesList.Count > 0) then
>>  begin
>>    Note := NotesList.Strings[0];
>>    NotesList.Delete(0);
>>    Result := PAnsiChar(Note);
>>  end
>>  else
>>    Result := '';
>> 
>>  LeaveCriticalSection(CritSectn);
>> end;
> 
> 
> That doesn't work either, the string assigned to the local variable is
> destroyed when it goes out of scope, that is when the function is
> left. 
> You have to change the function like below and have the caller
> allocate and free the memory the string is copied to:
> 
> {code untested}
> function ReadMessage(pBuf: PAnsiChar; pBufSize: PLongWord): LongWord;
> stdcall;
> begin
>  try
>    EnterCriticalSection(CritSectn);
>    try
>      if pBufSize = nil then
>      begin
>        Result := 0;
>      end
>      else if pBuf = nil then
>      begin // Return required size / number of AnsiChars
>        pBufSize^ := Length(NotesList[0]);
>        Result := 0;
>      end
>      else if pBufSize^ < Length(NotesList[0]) then
>      begin // Return required size / number of AnsiChars
>        pBufSize^ := Length(NotesList[0]);
>        Result := 0;
>      end
>      else begin // Return number of copied AnsiChars
>        Result := Length(NotesList[0]);
>        Move(Pointer(NotesList[0])^, pBuf^, Result);
>        NotesList.Delete(0);
>      end;
>    finally
>      LeaveCriticalSection(CritSectn);
>    end;
>  except
>    Result := 0;
>  end;
> end;
> {code}
> 
> But..
> If that function is called from different threads you cannot use it
> to get the size of a string in a first call with a nil pBuf since on
> the second call the string might no longer be the same.
> 
> --
> Arno Garrels
> 
> --
> To unsubscribe or change your settings for TWSocket mailing list
> please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
> Visit our website at http://www.overbyte.be
--
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to