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

Tony Pelton tpelton at gmail.com
Tue Jan 17 01:45:41 CET 2006


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