[fpc-devel] FPC shared lib called from C shared lib called from C main program crashes

Jonas Maebe jonas.maebe at elis.ugent.be
Thu Sep 17 11:50:59 CEST 2009


On 17 Sep 2009, at 11:33, Lukas Zeller wrote:

> I guess I really need to understand how the FPC runtime expects to  
> be initialized when located in a shared lib, but I couln't find any  
> hint so far in the FPC docs nor in the list archives.

Which FPC version are you using? I fixed shared library initialisation/ 
finalisation for Mac OS X and Linux in FPC 2.2.4. The only things you  
still have to watch out for are
a) don't pass ansistrings/widestrings/other reference counted types  
from one FPC shared library to another (they use different memory  
managers, so you'll get crashes when one tries to free memory  
allocated by another), or alternatively make sure that all libraries  
use the "cmem" memory manager
b) don't use these libraries in multi-threaded applications. It is  
possible to get them to work, but hard. See below for a text I posted  
last year to the mac-pascal list. It should still apply though. It was  
also about applications rather than libraries, but simply put the  
initialisation code in the initialisation section of your library  
rather than in the "begin..end." block of the main program.


Jonas

***
To properly initialise the threading system (only has to happen once  
at the start of your program), it's probably the easiest to create and  
then immediately destroy a dummy thread. The simplest way to do this:

uses
   cthreads,classes;
begin
   tthread.create(false).waitfor;
   <rest of your code>
end.

So, to recapitulate:
* add the above code at the start of your program (it will set  
ismultithread to true, amongst other things)
* define this helper function:

procedure CleanupThread;
{$if defined(VER2_2_0) or defined(VER2_2_2)}
var
   tm: tthreadmanager;
begin
   getthreadmanager(tm);
   tm.ReleaseThreadVars;
end;
{$else}
begin
   DoneThread;
end;
{$endif}

* and make your thread functions like this:

function threadfunc(parameter: pointer): longint; cdecl; { change to  
the signature expected by the Multiprocessing Services, but don't  
forget the "cdecl;"! }
begin
InitThread(stacksize);
RealThreadFunc(..);
CleanupThread;
end;
***



More information about the fpc-devel mailing list