I am using BCB 5.0 on NT and W2K platforms. My main question is what
does one need to do to create threads in a VCL application if you don't
want to use TThread?
For portability reasons, we are using a common thread class for managing
our threads that is based on the Win32 API. We are using this for
console applications as well as VCL applications. Threads in our VCL
applications that are not the main VCL thread simply use the Win32
SendMessage function to notify the VCL thread that a control needs to be
updated. This architecture has worked well for us in the past. Our
thread lasss was based on the _beginthreadNT API. Our new thread class
uses the _beginthreadex API; does this API ensure the heap is
thread-safe as does System::BeginThread?
From the BCB help files...
Begin Thread Description --------------------------------------
Use this routine or a TThread object to spawn separate threads of
execution instead of calling the CreateThread Win32API directly.
BeginThread encapsulates the Win32 CreateThread API call, but unlike
CreateThread, it ensures that the heap is thread-safe.
----------------------------------------------------
_beginthreadex Description ------------------------------------
Creates a thread and allows specifying the other parameters of the OS
API CreateThread (such as security and thread creation flags).
_beginthreadex calls _endthreadex when the thread finishes its
execution. _endthreadex does not close the thread handle, thereby
allowing other threads to block on this one without fear that the handle
will be freed out from under the system.
Other than the order of parameters and the closing of the thread handle,
_beginthreadex performs same operation as _beginthreadNT.
-----------------------------------------------
All my VCL applications seem to have the same problem. When they exit I
get a CodeGuard error after WinMain completes saying "Resource from
different RTL" (additional info provided below). Could it be that the C
run-time library is not getting properly initialized?
In a nutshell what I'm doing is this. I have a global variable that is
a derived class from fstream that I use for a log file that can be
written to by any thread in the app. My main thread spawns a log thread
that manages a double buffer so other threads can post data to the log
buffer w/o waiting for disk I/O because the log thread spools the buffer
to disk for them. That global variable is declared in the source file
containing WinMain and the declaration is outside of the WinMain
function itself.
Here's the call stack:
00475989 __internal_free
00475875 ___org_free
0048E0AA __thread_data_del
0048DC12 __cleanup
0048CED4 _exit
0048DDE8 __startup
CodeGuard references a line of code in one of my methods that uses the
localtime C library call as the one that allocated the memory causing
the problem. I don't save the address of the localtime buffer but
instead copy the contents so I don't know why this is an issue. Here's
the method:
void MyDateTime::Regenerate(void)
{
char buf[12]; //Avoids access overrun found by CodeGuard
struct timeb* TimeBuf = (struct timeb*)buf;
struct tm* dt;
::ftime(TimeBuf); //Get seconds since 1970
dt = localtime(&TimeBuf->time); //Line referenced
if (DateTime)
delete DateTime;
DateTime = new tm;
*DateTime = *dt;
DateTime->tm_year += BASE_YEAR;
++(DateTime->tm_mon);
mSec = TimeBuf->millitm;
TimeZone = "EST";
All input appreciated... thanks.
james.br...@jhuapl.edu