[fpc-pascal] static binding to C shared library (linux)

Alain Michaud Alain.Michaud at nrc-cnrc.gc.ca
Tue Jan 17 05:07:01 CET 2006


Hi,

thank-you for the reply.   

1 - I compile the C library myself. I even use it from a C program
compiled by me. Therefore for the C part, I am sure that everything is
OK. I also know that the path, and all that works. 

I can also access a string constant (the version number) from the
library using my pascal program.  

This makes me think that it has to do with the parameters. This one has
three. Unfortunately there is no other 'simple' function in the
library: 

int pl_setplparam (plPlotterParams * plotter_params, const char
*parameter, void *value)

which I translate into:

function pl_setplparam (plotter_params:plplotterparams; const
parameter:PCHAR; value:PCHAR):cint; cdecl; external 'plot';

please look at the last two parameters: one is "const" while the other
is not. Does that looks OK to you? Should I always use the same variable
names as the .h file? What should I do with the f... "void"?

Is the "cint" type equivalent to C: "int"  ? should I use "smallint"
instead.


2 - Someone tells me that old compilers would accept " * int" while the
new compilers would prefer a variable name: "variable * int" or "void *
int". Unless this the other way around then I should not use the
NO_VOID_SUPORT. So  I guess I do not worry about that one any more. 

3 - The file I have is "libplot.so" I think that this is a shared
library. Does that coresponds to "cdecl; external 'plot';"? If not, then
this is where my mistake was!!!!!!!

Is: external 'plot';  equivalent to: {$L liplot.so} or: {$Linklib
liplot.so} ?

4 - The structure  "plPlotterParams" is not defined in the .h file.
Belive it or not, there is only one line:

struct plPlotterParamsStruct plPlotterParams 

I understand that this is just a name change and plPlotterParamsStruct
was the name used inside the library. Why is this not defined remains a
mistery for me! Apparently the linker just assumes that it is a pointer!

You are right. The "user" is not supposed to access the "struct"
directly. This is only a handle for the second function, therefore there
was no need to define it in the .h file.   I guess I can find the
definition in the source code! However It seems to me that a "generic"
pointer should do. (What if did not have the source code)

Is the pascal type "pointer" EQUIVALENT to the C operator: '*' to a
struct?   

Thank you so much for reading

Alain


On Mon, 2006-01-16 at 19:45 -0500, Tony Pelton wrote:
> take what i have to say with a HUGE grain of salt because i have no
> idea what i'm talking about.
> 
> On 1/16/06, Alain Michaud <Alain.Michaud at nrc-cnrc.gc.ca> wrote:
> > Hi,
> >
> >  I would apreciate if someone could give me some advice please. In this
> > example:
> >
> > cfunction = function(theparameter:cint):cint;cdecl;external'theclib';
> >
> > It seems that this will not build unless I have the
> > file: /usr/local/include/theclib.h
> >
> > 1-Is this true?
> > 2-Does the FPC compiler read this .h file?
> > 3-Does the linker read this file?
> 
> not sure about that, i haven't done alot of work with external 'C' libs.
> 
> i have called DLL's written in 'C' before though ... and haven't had
> to worry about having the headers for them, as i've had Pascal files
> with the right stuff in them.
> 
> >
> >
> > The C prototypes for the two functions that I want to use look like
> > this:
> >
> > plPlotterParams * pl_newplparams(void)
> >
> > or:
> >
> > plPlotterParams * pl_newplparams
> >
> > and:
> >
> > int pl_setplparam (plPlotterParams * plotter_params, const char
> > *parameter, void *value)
> >
> > or:
> >
> > int pl_setplparam (plPlotterParams * plotter_params, const char
> > *parameter, char *value)
> >
> > The two set of prototypes exists because of a switch: "NO_VOID_SUPPORT"
> > to accept different compilers.
> >
> > 1 - Does anyone knows which case my compiler uses? "void" or "no_void"?
> 
> well ... i think that is some sort of 'C' pedantry having to do with
> whether you have to declare that your no-arg 'C' function takes 'void.
> 
> are you compiling this lib ? or is it already compiled for you ? or ?
> 
> i guess i should back up and ask the big question ... how are you
> trying to use this 'C' lib ?
> 
> as a shared library ?
> 
> i don't think Pascal should care about the void/no_void thingy.
> 
> >
> >
> > The first function "pl_newplparams" is suposed to allocate a structure
> > then return a handle. It seems that it returns something different than
> > "nil" but I am not sure if it is valid however.
> 
> your function, as you've written it here, appears to be returning a
> pointer to something of type 'plPlotterParams' ... presumably a
> struct.
> 
> >
> > This pointer is used as a parameter for the second function
> > "pl_setplparam".
> >
> > ERR := pl_setplparam(plotter_param,'PAGESIZE','letter');
> >
> > As soon as I call the function I get an "access" exception at the offset
> > 000000000. Although the function has 3 parameters, it could be the first
> > one (the pointer) that has the wrong type!
> >
> > I have tried many things like this:
> >
> > type
> > plplotterparams = record end;
> 
> i think you have a few issues :
> 
> a) you can't just make up your own record for the parameter type.
> 
> you've got to find the definition of plPlotterParams 'type' in the 'C'
> source, and then define a type in Pascal that matches it.
> 
> presumably, it is a 'C' struct, so you care going to define a Pascal
> "record" ... but you have to define the members of it properly.
> 
> once you've defined the "record" in Pascal to match the 'C' struct
> (assuming that is what it is) ... i think your Pascal code will go
> something like as follows :
> 
> Var my_params^ : pascal_plPlotterParams; // pointer to your pascal type
> 
> my_params := pl_newplparams();
> pl_setplparams(my_params,....);
> 
> >
> > function pl_newplparams:plplotterparams; cdecl; external 'plot';
> >
> > function pl_setplparam (plotter_params:plplotterparams; const
> > parameter:PCHAR; value:PCHAR):cint; cdecl; external 'plot';
> >
> > Can someone give me some hints on how to solve that problem. I have
> > spent the whole week-end on these three lines and I am quite frustrated
> > right now!  The package is called "libplot" ("plotutils") and I was
> > planning to put it on the web if I can get it to work. :(
> 
> so yeah ...
> 
> as i've said ... i _think_ you have 2 primary problems :
> 
> a) you've got to define a type in Pascal that matches the "type" that
> your first function returns.
> b) you've got to use Pascal "pointer" syntax when defining your
> "handle" in Pascal for the variable you are going to use to capture
> the pointer being return from your func.
> 
> btw ... i _suspect_ that, if you aren't going to _use_ the value being
> return from the first function, you could just use a "void" pointer
> type in pascal to retrieve the address of  the thing being emitted
> from the first function ... and just pass it to the second.
> 
> Var my_point : Pointer;
> 
> my_point := firstfunction();
> secondfunction(my_point);
> 
> ... or something like that.
> 
> of course, if you actually want to manipulate the thing being
> returned, to modify it's members or something ... you will have to
> define stuff in Pascal so the compiler can generate the code needed to
> get at the members within.
> 
> >
> > Thank you for reading
> 
> all guesses ... but sure ...
> 
> >
> > Alain Michaud
> 
> Tony
> 
> --
> X-SA user ? 0.4 is out !
> http://x-plane.dsrts.com
> http://games.groups.yahoo.com/group/x-plane-foo/




More information about the fpc-pascal mailing list