Board index » cppbuilder » Callback, Dll, Thread and synchronization HELP!

Callback, Dll, Thread and synchronization HELP!


2007-02-08 03:42:54 AM
cppbuilder96
Hi All:)
I have a complicate (for my skills) problem..
I have a console apllication. It loads a dll that I wrote.
This dll works like a TCP Client. It creates a thread from within it
receives data from a TCP connection.
The console application passes a callback function to the initialization
function of the dll. Inside the dll's thread the callback is called to
process the data received. All works fine if I call the callback
function from within the thread.
But when I try to call it from a method called with Synchronize inside
the thread, it stops working :( The not working code:
Inside the dll:
typedef void (*RECEIVETXTPROC)(char* Txt);
RECEIVETXTPROC OnReceiveTxt;
bool Initialize(char* ServerIPAddress,
int Port,
bool ActivateAsynchronousReception,
RECEIVETXTPROC OnReceiveCallback,
bool UseStartingDelimiter,
char StartingDelimiter,
char EndingDelimiter)
{
...
OnReceiveTxt=OnReceiveCallback;
...
}
class TReceiverThread : public TThread
{
public:
AnsiString RvdTxt;
...
}
//the following class is responsable of creating and destroying the thread.
class AsynchronousReceiverClass
{
private:
TReceiverThread* ReceiverThread;
...
public:
void __fastcall ExecuteCallBack();
...
}
void __fastcall AsynchronousReceiverClass::ExecuteCallBack()
{
if(OnReceiveTxt)
OnReceiveTxt(ReceiverThread->RvdTxt.c_str() );
}
AsynchronousReceiverClass* AsynchRec=NULL;
void __fastcall TReceiverThread::Execute()
{
...
RvdTxt=Txt;//Txt contains the received string
//AynchRec is a global instance of AsynchronousReceiverClass
Synchronize(AsynchRec->ExecuteCallBack);
...
}
//Inside the console application:
void OnAsynchReceiveCommand(char* Buffer)
{
// do stuff with the string
}
//the following is loaded from the dll
Initialize(ServerIPAddress,
Port,
false,
OnAsynchReceiveTxt,//callback for asynch reception
true,
'?,
'?
);
if I just put the code written inside ExecuteCallBack() into the Thread
all works fine, even if I think it's not thread safe :(
What should I do?
Thank U in advance,
Stefano B.
 
 

Re:Callback, Dll, Thread and synchronization HELP!

"Stefano Bonifazi" < XXXX@XXXXX.COM >wrote in message
Quote
But when I try to call it from a method called with Synchronize
inside the thread, it stops working :(
Your console app does not have a VCL message queue to process the
Synchronize() requests.
Gambit
 

Re:Callback, Dll, Thread and synchronization HELP!

Thank You very much Mr Lebeau!
Quote
Your console app does not have a VCL message queue to process the
Synchronize() requests.
I did not know such was needed at all!!
I cannot create that queue and I cannot use VCL at all in the console..
Is there any other solution? Part of my code is inside a dll ... so how
can I create "synchronization".. be sure that there would not be problems?
Thank U in advance.
Stefano B.
 

{smallsort}

Re:Callback, Dll, Thread and synchronization HELP!

"Stefano Bonifazi" < XXXX@XXXXX.COM >wrote in message
Quote
I did not know such was needed at all!!
Synchronize() uses window messages internally.
Quote
I cannot create that queue
Yes, you can. Simply have main() call Application->ProcessMessages()
in a loop for the lifetime of the process.
Quote
I cannot use VCL at all in the console..
Yes, you can. And you already are - TThread is a VCL class.
Quote
Part of my code is inside a dll ... so how can I create
"synchronization"..
You don't. Not from inside the DLL, anyway. That is the
application's responsibility. Have the DLL call the callback in the
context of the thread, and then the application has to make sure its
callback is actually thread-safe.
Gambit
 

Re:Callback, Dll, Thread and synchronization HELP!

Hi Mr.Lebeau, Thank U for Ur reply!
Remy Lebeau (TeamB) wrote:
Quote
>I cannot create that queue

Yes, you can. Simply have main() call Application->ProcessMessages()
in a loop for the lifetime of the process.
No I can't sorry, but I cannot modify the console application so much :(
That is not my code, and it's not written for a Borland compiler at
all:( Maybe it will be even compiled for Linux (So I should even find a
way to make my clx code compile in Linux :( .. Check the other post into
Socket group about indy and CLX )the other programmers r going to use my
code through my dll. I can do whatever in my dll, but very few
modifications to the console application...
Quote
You don't. Not from inside the DLL, anyway. That is the
application's responsibility. Have the DLL call the callback in the
context of the thread, and then the application has to make sure its
callback is actually thread-safe.

Ok. I've exported 3 functions from my dll:
bool TryEnterInThreadSafeCode()
{
if(CritSectInit)
return TryEnterCriticalSection(&CriticalSection);
else
return false;
}
void WaitForEnteringInThreadSafeCode()
{
if(CritSectInit)
EnterCriticalSection(&CriticalSection);
}
void LeaveThreadSafeCode()
{
if(CritSectInit)
LeaveCriticalSection(&CriticalSection);
}
The Critical Section is initializated in the Initialize function of my
DLL, and deleted in its Close function (the first and last the user must
call!)
Then I require the callback function inside the console application to be:
void OnAsynchReceiveCommand(char* Buffer)
{
WaitForEnteringInThreadSafeCode();
//do their stuff
LeaveThreadSafeCode();
}
and anytime in the main thread they require to read memory used by the
second thread
if(TryEnterInThreadSafeCode())
{
//do whatever with shared memory
LeaveThreadSafeCode();
}
All seems to work... is that thread safe?
Thanks again!
Stefano B.
 

Re:Callback, Dll, Thread and synchronization HELP!

Quote
>>I cannot create that queue
>...
No I can't sorry, but I cannot modify the console application so much :(
If that were my situation I would consider doing this in the DLL:
Register a windows message
Create a message-only window
Post that windows message to the window
When that message is received, post it again
. Ed
Quote
Stefano Bonifazi wrote in message
news: XXXX@XXXXX.COM ...
 

Re:Callback, Dll, Thread and synchronization HELP!

"Stefano Bonifazi" < XXXX@XXXXX.COM >wrote in message
Quote
That is not my code, and it's not written for a Borland compiler at
all:(
Then you are out of luck. Non-Borland compilers can't handle the VCL
at all. So you can't do anything in your DLL that requires VCL-level
interactions with the hosting application. That means no
Synchronize() at all.
Quote
The Critical Section is initializated in the Initialize function of
my
DLL, and deleted in its Close function (the first and last the user
must
call!)
You are going about this all wrong. You are not responsible for
providing thread-safety functions for the application to use.
Especially if you are going to compile your DLL for other platforms,
so you can't use platform-specific objects anyway. The application
has to manage its own thread safety on its own outside of your DLL.
Gambit
 

Re:Callback, Dll, Thread and synchronization HELP!

Hi Mr Mulroy!
Thank U for Ur reply.
Quote
If that were my situation I would consider doing this in the DLL:

Register a windows message
Create a message-only window
Post that windows message to the window
When that message is received, post it again
I can't register windows at all :( that code should be recompiled in
other platforms :( And so only slight modification are allowed :( ... I
can for example provide those functions EnterInThreadSafeCode,
ExitInThreadSafeCode, allowing the developer who will port into linux
the console to reinplement those 2 functions in a specific way for his
OS... Basing all the stuff on windows messages would mean rebuilding all
in a OS that works differently :(
Thank U anyway!
Regards,
Stefano B.
 

Re:Callback, Dll, Thread and synchronization HELP!

Hi mr. Lebeau! Thank U!
Quote
>The Critical Section is initializated in the Initialize function of
my
>DLL, and deleted in its Close function (the first and last the user
must
>call!)

You are going about this all wrong. You are not responsible for
providing thread-safety functions for the application to use.
Especially if you are going to compile your DLL for other platforms,
so you can't use platform-specific objects anyway. The application
has to manage its own thread safety on its own outside of your DLL.
Well I expressed myself badly :( ... On the console application I wrote
a C++ unit (no BCB!) responsible of loading dynamically my DLL and that
actually furnishes the interface for working with the DLL. So for
example the initialize function on that unit calls the Initialize
function on the DLL in Win32 way (LoadLibrary, GetProcAddress...) So in
that function that is in the console application I can create the
Critical Section. The DLL itself is free of that stuff, so it can be
recompiled fine everywhere (please check my thread about CLX and indy in
the socket group, I dunno what to do :( ).. The developer who will port
my code on another platform should only rewrite that small unit for
loading the dll and its methods in a OS specific fashion.
So he can reinplement those functions EnterInThreadSafeCode and
LeaveThreadSafeCode, in a specific way for his OS.
The DLL is free from that code :)
Hope thies way is correct.. I think I am doing what U say, cause only
the console application is responsible for thread safe code, not my dll...
Thank You,
Best regards,
Stefano B.
 

Re:Callback, Dll, Thread and synchronization HELP!

If you have to run on such diverse multiple platforms as to not be able to
have messaging then how can you use a DLL, threads or even consider if
something is console mode?
Almost any windowing operating system has messages and window procedures,
although what they are called and the specifics of them vary. You are
looking to do a platform-specific task and the solution to it will therefore
be platform-specific. Figure out how to solve it under each of the target
OS systems and conditionally compile for each.
. Ed
Quote
Stefano Bonifazi wrote in message
news: XXXX@XXXXX.COM ...

Hi Mr Mulroy!
Thank U for Ur reply.


>If that were my situation I would consider doing this in the DLL:
>
>Register a windows message
>Create a message-only window
>Post that windows message to the window
>When that message is received, post it again

I can't register windows at all :( that code should be recompiled in other
platforms :( And so only slight modification are allowed :( ... I can for
example provide those functions EnterInThreadSafeCode,
ExitInThreadSafeCode, allowing the developer who will port into linux the
console to reinplement those 2 functions in a specific way for his OS...
Basing all the stuff on windows messages would mean rebuilding all in a OS
that works differently :(
Thank U anyway!
Regards,
Stefano B.