Recent

Author Topic: Trying to link to 3rd party, c, .so.  (Read 8724 times)

jbmckim

  • Full Member
  • ***
  • Posts: 144
Trying to link to 3rd party, c, .so.
« on: December 15, 2017, 10:55:05 pm »
I'm prototyping an app that I'd like to port between Windows and Linux.  I'm having trouble linking (static) to a library.  c code is the source language of the library (which I have).

Here's the Windows function declaration.  It works (i.e. compiles, links, runs) fine:

Code: Pascal  [Select][+][-]
  1.  function seabreeze_open_spectrometer(iWorking:Integer; errorcode:PInteger):Integer; cdecl;
  2.              external 'C:\windows\system32\seabreeze.dll';
 
         
Here's the Linux function declaration.  It compiles but does not link:

Code: Pascal  [Select][+][-]
  1. function seabreeze_open_spectrometer(iWorking:Integer; errorcode:PInteger):Integer; cdecl;
  2.                         external '/home/pi/Documents/ScratchProjects/libseabreeze.so';
 
         
The error is "Generic error while linking."  I've isolated my problem to this statement by commenting and uncommenting same.

I'm primarily a Windows jockey, not so much Linux. Given the examples, it looks like this should do it.  However, in the absence of a full fledged working example (the examples are pseudo code or snippets in forum comments), its difficult to tell.

Any help is appreciated.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Trying to link to 3rd party, c, .so.
« Reply #1 on: December 15, 2017, 11:41:43 pm »
You may need to install libseabreeze.so into a system library directory such as
  /usr/local/lib
Then it will be in your default library path.

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Trying to link to 3rd party, c, .so.
« Reply #2 on: December 16, 2017, 12:58:21 am »
Do not use full path name for your libraries.

jbmckim

  • Full Member
  • ***
  • Posts: 144
Re: Trying to link to 3rd party, c, .so.
« Reply #3 on: December 16, 2017, 02:48:42 am »
howardpc - There's a copy there as well and when the path name is omitted the link dies with the same error.

Cyrax - Sure but this is a prototype and part of the point is to understand where everything is.  If there's an operational reason for this, please explain.

Thanks.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Trying to link to 3rd party, c, .so.
« Reply #4 on: December 16, 2017, 06:28:59 am »
External clause doesn't even expect you to write the prefix and extension, let alone the full path. Just specify the name then use -Fl to point the compiler where to find these libraries, by default it will be searched on library path, which includes current directory on windows and everything in PATH and everything in the contents of /etc/ld.so.conf.d/* (at least /usr/lib should be there, but current directory won't be).

balazsszekely

  • Guest
Re: Trying to link to 3rd party, c, .so.
« Reply #5 on: December 16, 2017, 05:59:38 pm »
You can also load the library dynamically.

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Trying to link to 3rd party, c, .so.
« Reply #6 on: December 16, 2017, 09:24:05 pm »
c code is the source language of the library (which I have).

If you have a C-source, why don't you link it directly?
This works for me on Linux:

Code: C  [Select][+][-]
  1. // myCfile.c
  2. int myIntFunc(__u16 par1, __s32 par2) { return 12345; }
  3.  

Code: Pascal  [Select][+][-]
  1. unit MyCCodeIntf;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, ctypes {, cmem, cthreads ?};
  9.  
  10. {$Link myCfile.o}
  11.  
  12. // Pascal is anycase
  13. function MyIntFunc(par1 : cuint16; par2 : cint32) : cint; cdecl;external name 'myIntFunc';
  14.  
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

jbmckim

  • Full Member
  • ***
  • Posts: 144
Re: Trying to link to 3rd party, c, .so.
« Reply #7 on: December 17, 2017, 04:50:09 am »
sash - wasn't aware that was a possibility. So this looks like it links to the .o files? 

Never the less, it looks like linking to the .so is also supported.  Any thoughts and why this isn't working?

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Trying to link to 3rd party, c, .so.
« Reply #8 on: December 17, 2017, 02:08:22 pm »
Quote
So this looks like it links to the .o files?  Any thoughts and why this isn't working?
Yes, gcc-compiled object files.

In addition to above advices,

Did you tried LoadLibrary approach? Are you sure you have same target options (cpu, platform, bitness), so your lib is actually loadable by host app?

Also, try to see how implemented Pascal wrappers for some working projects, APIs. Something like SDL etc.
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

Deepaak

  • Sr. Member
  • ****
  • Posts: 454
Re: Trying to link to 3rd party, c, .so.
« Reply #9 on: December 17, 2017, 02:39:42 pm »
Never the less, it looks like linking to the .so is also supported.  Any thoughts and why this isn't working?

.so file is a dynamic library one cannot load it statically. You have to ship the .so (dynamic library) with your application.

Simple Method

Code: Pascal  [Select][+][-]
  1. function MyIntFunc(par1 : Integer; par2 : Integer) :Integer; cdecl; external 'libName.so' name 'myIntFunc';

Complex Method
Code: Pascal  [Select][+][-]
  1. uses ...dynlibs...
  2.  
  3. procedure UseDLL;
  4. type
  5.   TMyIntFunc=function (aInt:Integer; bInt: Integer):Integer; StdCall;
  6. var
  7.   MyLibC: TLibHandle= dynlibs.NilHandle;
  8.   MyIntFunc: TMyIntFunc;
  9.   FuncResult: string;
  10. begin
  11.   MyLibC := LoadLibrary('libc.' + SharedSuffix);   //libc.so
  12.   if MyLibC = dynlibs.NilHandle then Exit;  //DLL was not loaded successfully
  13.   MyIntFunc:= TMyIntFunc(GetProcedureAddress(MyLibC, 'MyIntFunc');
  14.   FuncResult:= MyIntFunc(5,3);  //Executes the function
  15.   if MyLibC <>  DynLibs.NilHandle then if FreeLibrary(MyLibC) then MyLibC:= DynLibs.NilHandle;  //Unload the lib, if already loaded
  16. end;


As mentioned by you, If you have the C Source code for the library. Then you have the option for dynamic linking as well as static linking. Dynamic linking is straight forward method. But if you like you can compile the code to make a static library (.a) and then you can link it with your executable without the need of distributing with your application.
« Last Edit: December 17, 2017, 02:45:18 pm by Deepaak »
Holiday season is online now. :-)

jbmckim

  • Full Member
  • ***
  • Posts: 144
Re: Trying to link to 3rd party, c, .so.
« Reply #10 on: December 18, 2017, 08:54:52 pm »
Deepak - FuncResult s/b Integer?

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Trying to link to 3rd party, c, .so.
« Reply #11 on: December 18, 2017, 09:07:37 pm »
Yes. Not string. It should actually be PrUint
Specialize a type, not a var.

jbmckim

  • Full Member
  • ***
  • Posts: 144
Re: Trying to link to 3rd party, c, .so.
« Reply #12 on: December 19, 2017, 04:22:03 am »
Still no success.  Tried the $Link statement against both an .o that is a member of the .so library and contains the call I'm using and the .so.

Tried the dynamic link and the LoadLibrary statement returns 0.

Here's the code:

Code: Pascal  [Select][+][-]
  1.     bFoundFile := false;
  2.     bFoundFile := FileExists('libseabreeze.so');
  3.     SeabreezeLibC := LoadLibrary('libseabreeze.so');  
  4.     if SeabreezeLibC = dynlibs.NilHandle then Exit;

Note that bFound gets set to "true" so I'm pretty comfortable the file is being seen.  Any ideas as to why the .so is not loading?

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Trying to link to 3rd party, c, .so.
« Reply #13 on: December 19, 2017, 04:27:07 am »
Note that bFound gets set to "true" so I'm pretty comfortable the file is being seen.  Any ideas as to why the .so is not loading?

Per FPC docs, try a complete path to the library in LoadLibrary:

https://www.freepascal.org/docs-html/rtl/dynlibs/loadlibrary.html


jbmckim

  • Full Member
  • ***
  • Posts: 144
Re: Trying to link to 3rd party, c, .so.
« Reply #14 on: December 19, 2017, 07:28:41 pm »
Phil - I'd tried that previously and received some constructive criticism for it but in the end I agree with both you and the Lazarus documentation suggestion for the reason they state there.  This is how I deploy in the W environment for the reasons they state.

The copyrights on this package allow general distribution and publishing so I'll include some things here that might help if people want to take a deeper look.  (I didn't do this before because I assumed this was something obvious and silly that I was doing - which it probably still is.)

Therefore, the .h of the routines I'm trying to reference is attached.  (I tried to upload the .so but its too large - it links to more than the routines found in this .h(Seabreeze.txt)).  My .pas(Unit.txt) is also attached. If anyone wants my demo project to look at (its small and stupid simple), you're welcome to that just ask.

Thanks.

 

TinyPortal © 2005-2018