Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-12

Shared libries

17 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Torsten Bonde Christiansen

Hi.

I'm trying to create a shared library (under linux) and I not sure what the difference between the modifier *export* and the section *exports* is? Or perhaps
when to use one and the other...

I have read both the programmers guide (7.2) and reference guide (11.9.3) but this
didn't really help me.

Kind regards,
Torsten Bonde Christiansen.

Unknown author
to Torsten Bonde Christiansen
Show quoted text 7 lines
Hi. I'm trying to create a shared library (under linux) and I not sure what the difference between the modifier *export* and the section *exports* is? Or perhaps when to use one and the other...

Just different ways of doing it.

You can export each one, or you can use exports clause to do it all there in one place. I think it is from the old borland days when they used to do the export, but then they added exports as a feature.. but I'm not 100 percent sure.

A long time ago when I was using libraries on linux, I had some problems, with initialization and finalization sections, I'm not sure if the problems are fixed. Also on BSD it didn't load libraries back then, not sure if it has changed.

ik
to Torsten Bonde Christiansen: Hi. I'm trying to create a shared library (under linux) and I not sure what the…
Torsten Bonde Christiansen wrote 7 lines
Hi. I'm trying to create a shared library (under linux) and I not sure what the difference between the modifier *export* and the section *exports* is? Or perhaps when to use one and the other...

export means that you can control the name of a symbol in how it will be in the elf file itself of the so.
So you call your original procedure Foo, but you export it as 'baz', so using objdump in Linux, you'll find "baz" and not "Foo".

Exports, is the way to tell the compiler what are the symbols you wish to make available for reuse in the so file itself, so I could bind to them.

Show quoted text 12 lines
I have read both the programmers guide (7.2) and reference guide (11.9.3) but this didn't really help me. Kind regards, Torsten Bonde Christiansen. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Torsten Bonde Christiansen
to ik
ik wrote 20 lines
On Sun, Dec 11, 2011 at 23:35, Torsten Bonde Christiansen < > wrote: Hi. I'm trying to create a shared library (under linux) and I not sure what the difference between the modifier *export* and the section *exports* is? Or perhaps when to use one and the other... export means that you can control the name of a symbol in how it will be in the elf file itself of the so. So you call your original procedure Foo, but you export it as 'baz', so using objdump in Linux, you'll find "baz" and not "Foo". Exports, is the way to tell the compiler what are the symbols you wish to make available for reuse in the so file itself, so I could bind to them.

So in the following example "foo" would not be visible (neither as "foo" nor "bar") to other program (eg. a C-program) unless I added an *exports* section?

library test;
function foo(a: integer): integer; [export, alias: 'bar'];
begin
   result := a * a;
end;
end.

Basically what i'm trying to do, is use a lot of units and I want avoid creating a HUGE *exports* section but rather name the methods in the units instead.

Regards,
Torsten Bonde Christiansen.

Jonas Maebe
to Torsten Bonde Christiansen
Torsten Bonde Christiansen wrote
So in the following example "foo" would not be visible (neither as "foo" nor "bar") to other program (eg. a C-program) unless I added an *exports* section?

Correct. See also http://bugs.freepascal.org/bug_view_advanced_page.php?bug_id=18552

Basically what i'm trying to do, is use a lot of units and I want avoid creating a HUGE *exports* section but rather name the methods in the units instead.

That is not possible. Whether or not a routine is exported is a property of the library, not of the individual units that are used (directly or indirectly) by the library.

Jonas

Torsten Bonde Christiansen
to Jonas Maebe
Jonas Maebe wrote 13 lines
On 11 Dec 2011, at 23:18, Torsten Bonde Christiansen wrote: > So in the following example "foo" would not be visible (neither as "foo" nor "bar") to other program (eg. a C-program) unless I added an *exports* section? Correct. See also http://bugs.freepascal.org/bug_view_advanced_page.php?bug_id=18552 > Basically what i'm trying to do, is use a lot of units and I want avoid creating a HUGE *exports* section but rather name the > methods in the units instead. That is not possible. Whether or not a routine is exported is a property of the library, not of the individual units that are used (directly or indirectly) by the library. Jonas_______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Ok, thanks for clearifying that. I guess it's going to be a lot of include files instead... :)

-Torsten.

Unknown author
to Torsten Bonde Christiansen
Ok, thanks for clearifying that. I guess it's going to be a lot of include files instead... :) -Torsten.

Why do you need include files in your case?
You can put the units in the uses clause of your library.

library something;
uses
  someunit;
exports
  someunit.yourproc;
end.

The someunit. prefix is optional.

In newer versions of FPC it allows you to put an exports clause in the unit itself, but older versions didn't allow it.

http://62.166.198.202/bug_view_page.php?bug_id=4398&history=1

In delphi 1.0 the export directive meant something different which causes confusion. Borland made export directive obsolete but kept the export keyword there probably for compiling old code. fpc has slightly different reasons for the export directive than delphi and lots of confusion arises.

Torsten Bonde Christiansen
to Unknown author: Why do you need include files in your case? You can put the units in the uses clause of…
Show quoted text 9 lines
> Ok, thanks for clearifying that. I guess it's going to be a lot of > include files instead... :) > > -Torsten. Why do you need include files in your case? You can put the units in the uses clause of your library.

Because it is still going to give me a very long list of exports - considering I have approx. 200 methods to export.

Instead I would do something like this:

library something;
{$DEFINE InterfaceSection}
{$I unit1}
[snip...]
{$I unit20}
{$UNDEFINE InterfaceSection}
exports
{$DEFINE ExportSection}
{$I unit1},
[snip...]
{$I unit20}
{$UNDEFINE ExportSection}
;
end.
unit 1;
{$IFDEF InterfaceSection}
function Foo(a: integer): integer;
begin
   result := a * a;
end;
{$ENDIF}
{$IFDEF ExportSection}
   Foo name 'Bar'
{$ENDIF}
Unknown author
to Torsten Bonde Christiansen
Show quoted text 45 lines
On 2011-12-12 00:48, wrote: > >> Ok, thanks for clearifying that. I guess it's going to be a lot of >> include files instead... :) >> >> -Torsten. > > > Why do you need include files in your case? > You can put the units in the uses clause of your library. Because it is still going to give me a very long list of exports - considering I have approx. 200 methods to export. Instead I would do something like this: library something; {$DEFINE InterfaceSection} {$I unit1} [snip...] {$I unit20} {$UNDEFINE InterfaceSection} exports {$DEFINE ExportSection} {$I unit1}, [snip...] {$I unit20} {$UNDEFINE ExportSection} ; end. unit 1; {$IFDEF InterfaceSection} function Foo(a: integer): integer; begin result := a * a; end; {$ENDIF} {$IFDEF ExportSection} Foo name 'Bar' {$ENDIF}

Well maybe ExportAll compiler feature should be suggested?

But please try this

unit Unit1;
{$mode objfpc}{$H+}
interface
procedure proc1; stdcall;
procedure proc2; stdcall;
implementation
procedure proc1; stdcall;
begin
  writeln('hello');
end; exports proc1;
procedure proc2; stdcall;
begin
  writeln('hello 2');
end; exports proc2;
end.

Notice how I put exports in several places...

It works on win32..

Try linux?

Now for your executable, load it like so:

program p;
{$mode objfpc}{$H+}
procedure proc1; stdcall; external 'd2.dll';
procedure proc2; stdcall; external 'd2.dll';
begin
  writeln('First proc from lib..<enter>');
  readln;
  proc1;
  readln;
  writeln('Second proc from lib..<enter>');
  proc2;
  readln;
end.
Torsten Bonde Christiansen
to Jonas Maebe
Jonas Maebe wrote 20 lines
On 12 Dec 2011, at 19:56, wrote: > procedure proc1; stdcall; > begin > writeln('hello'); > end; exports proc1; > > procedure proc2; stdcall; > begin > writeln('hello 2'); > end; exports proc2; > > > end. > > > Notice how I put exports in several places... > > It works on win32.. It only partially works. Please see the bug report I mentioned earlier: http://bugs.freepascal.org/bug_view_advanced_page.php?bug_id=16070

Does this just mean I have to compile my library with -B every time? If that is the case, then I don't mind.

I prefer to have a more manageable unit structure at the cost of an extra compiler option, than dealing with
lots of includes or a very large exports section.

Regards,
Torsten.

Torsten Bonde Christiansen
to Unknown author: Well maybe ExportAll compiler feature should be suggested? But please try this unit Unit1;
Show quoted text 30 lines
Well maybe ExportAll compiler feature should be suggested? But please try this unit Unit1; {$mode objfpc}{$H+} interface procedure proc1; stdcall; procedure proc2; stdcall; implementation procedure proc1; stdcall; begin writeln('hello'); end; exports proc1; procedure proc2; stdcall; begin writeln('hello 2'); end; exports proc2; end.

I tried and it didn't seem to work, however perhaps it could be related to that I'm trying to create a library for arm-linux on android.

I've been following the guides from
http://wiki.lazarus.freepascal.org/Custom_Drawn_Interface/Android which i know probably is trying to
do something that's not possible.

Anyway, thanks to both of you for the help so far.

Regards,
Torsten.

Unknown author
to Torsten Bonde Christiansen
Show quoted text 33 lines
> > > Well maybe ExportAll compiler feature should be suggested? > > But please try this > > unit Unit1; > > {$mode objfpc}{$H+} > > interface > > procedure proc1; stdcall; > procedure proc2; stdcall; > > implementation > > > procedure proc1; stdcall; > begin > writeln('hello'); > end; exports proc1; > > procedure proc2; stdcall; > begin > writeln('hello 2'); > end; exports proc2; > > > end. I tried and it didn't seem to work, however perhaps it could be related to that I'm trying to create a library for arm-linux on android.

Try adding EXPORT keyword after the stdcall.

I forgot to put that in there, that's what i used, but I figured it was not needed so I deleted it before I sent my message. I thought export keyword was not used for exports..

Unknown author
to Jonas Maebe: It only partially works. Please see the bug report I mentioned earlier:…
Show quoted text 25 lines
On 12 Dec 2011, at 19:56, wrote: > procedure proc1; stdcall; > begin > writeln('hello'); > end; exports proc1; > > procedure proc2; stdcall; > begin > writeln('hello 2'); > end; exports proc2; > > > end. > > > Notice how I put exports in several places... > > It works on win32.. It only partially works. Please see the bug report I mentioned earlier: http://bugs.freepascal.org/bug_view_advanced_page.php?bug_id=16070

interesting, I tried BUILD ALL in lazarus ide and it works, but I also tried not building all and using the EXPORT keyword along with EXPORTS section, and that requires no build all. Whereas without the EXPORT keyword it only works if you build all. This is on win32.

So the export keyword does something on win32?

You said that EXPORT keyword is for emx and os/2 ...

But maybe I should look into the compiler sources to see if it does something else.. it seems to cause the dll to work without a build all..

Tomas Hajny
to Unknown author
Show quoted text 33 lines
> On 12 Dec 2011, at 19:56, wrote: > >> procedure proc1; stdcall; >> begin >> writeln('hello'); >> end; exports proc1; >> >> procedure proc2; stdcall; >> begin >> writeln('hello 2'); >> end; exports proc2; >> >> >> end. >> >> >> Notice how I put exports in several places... >> >> It works on win32.. > > It only partially works. Please see the bug report I mentioned earlier: > http://bugs.freepascal.org/bug_view_advanced_page.php?bug_id=16070 > > interesting, I tried BUILD ALL in lazarus ide and it works, but I also tried not building all and using the EXPORT keyword along with EXPORTS section, and that requires no build all. Whereas without the EXPORT keyword it only works if you build all. This is on win32. So the export keyword does something on win32? You said that EXPORT keyword is for emx and os/2 ...

.
.

It's intended to be supported under OS/2 and EMX indeed. However, the compiler probably won't do much with EXPORT under EMX and OS/2 either as of now (it doesn't work due to issues with the GNU linker available for OS/2).

Tomas