Recent

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

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Trying to link to 3rd party, c, .so.
« Reply #15 on: December 19, 2017, 11:55:44 pm »
Quote
I'd tried that previously and received some constructive criticism

FileExists and LoadLibrary - are functions, require a filename: absolute, relative, omitted paths rules work here, like for any other file.

Shared library name near procedure signature declaration - is an instruction for compiler, a dynamic library name, works accordingly to library search paths rules (platform dependent).

As I guessed before, by some reason, your .so library is not loadable (did you check target options match?), you didn't provide details about environment, os, compiler.

Try minimal working sample (without real code at all) to learn basics about static/dynamic linking, how it works across platform/languages. I gave you some "helloworld" to start. When it will work, proceed with your real code.
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 #16 on: December 20, 2017, 01:59:43 am »
sash - Ah!  You're right.  I didn't provide info.  Here it is:  This is Raspian running Jessie.  Lazarus is 1.6.4 and FPC is 3.0.4.

With regard to the "hello world" suggestion, please see my previous attachment (unit.txt).  It has a button that attempts to call the .so.

I'd appreciate it if someone would look at seabreeze.txt (the .h file that builds the wrapper I'm trying to call) and compare what is there to how my unit.txt (.pas) is calling it.  As I've said elsewhere, this all works fine in Windows but there may be a formatting difference required by linux and the .so.

Thanks.


Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Trying to link to 3rd party, c, .so.
« Reply #17 on: December 20, 2017, 04:00:03 am »
sash - Ah!  You're right.  I didn't provide info.  Here it is:  This is Raspian running Jessie.  Lazarus is 1.6.4 and FPC is 3.0.4.

I've gotta ask: Do you have the right .so? That is, 32-bit vs 64-bit, Intel vs Arm, that sort of thing.

See what you have:

file libseabreeze.so

You can also check its dependencies:

ldd libseabreeze.so

Once you get your test code working, you might find some of this helpful for creating and using dynamic libraries:

https://macpgmr.github.io/MacXPlatform/PascalDynLibs.html

Part 1 is about creating a dynamic library with Pascal and calling it from other languages; Part 3 gives an example of calling a C library (GDAL) from Pascal code.

jbmckim

  • Full Member
  • ***
  • Posts: 144
Re: Trying to link to 3rd party, c, .so.
« Reply #18 on: December 20, 2017, 08:10:31 am »
Phil - Good thought.  I didn't mention that I built the lib from source (its a gcc build) on the raspberry and have tested it with sample programs (gcc again) from the vendor.

I will look at ldd again tomorrow its a bit daunting since the library is huge.  I'll also check out your link tomorrow.

My contact at the vendor said they've had people do c#, vb.net, VS c++ and various c(++) implementations under linux and unix but no one's ever tried pascal.  Honestly, I wouldn't be trying it either but for the fact that with LP everything is integrated in the IDE/compiler set.  No 3rd party items needed other than the interface.

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Trying to link to 3rd party, c, .so.
« Reply #19 on: December 20, 2017, 09:24:28 pm »
Phil - Good thought.  I didn't mention that I built the lib from source (its a gcc build) on the raspberry and have tested it with sample programs (gcc again) from the vendor.

Since you're apparently hung up trying to get LoadLibrary to work, why not let the OS load the library automatically at startup instead of doing it manually? That might rule out the unlikely issue with LoadLibrary. I normally don't use LoadLibrary. It's most useful, for example, if the app can still be used even if a library can't be loaded, or if you might be loading different versions of a library where newer functions aren't part of older versions - otherwise it probably just makes sense to shut down the app if the OS can't load the library.

Simplifies your code quite a bit too. Note that you can write your external declarations in a way that allows you to conditionally switch between loading manually or automatically like this:

{$IFDEF LOAD_DYN}type Tseabreeze_open_spectrometer = function{$ELSE}function seabreeze_open_spectrometer{$ENDIF}
  (iWorking:Integer; errorcode:PInteger):Integer;
    {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
    {$IFNDEF LOAD_DYN}external LibNameBase;{$ENDIF}

{$IFDEF LOAD_DYN}
var
  seabreeze_open_spectrometer : Tseabreeze_open_spectrometer;
begin
  seabreeze_open_spectrometer := GetProcAddress(LibHandle, 'seabreeze_open_spectrometer');
{$ENDIF}

The calling code then is the same regardless of how the library is loaded.

Note: Check your DllDecl.h file to see how DLL_DECL is actually defined. I'm guessing that it's stdcall with Windows and cdecl with Linux and macOS.
« Last Edit: December 20, 2017, 09:32:54 pm by Phil »

jbmckim

  • Full Member
  • ***
  • Posts: 144
Re: Trying to link to 3rd party, c, .so.
« Reply #20 on: December 20, 2017, 11:02:59 pm »
I'll be checking this this evening. (Survivor Finale for wife and daughter - I will actually be throwing myself off the TV island - I'd rather fight the library wars - or maybe gouge out my eyes.)

It occurred to me that one thing I haven't mentioned is that the library is a single file, libseabreeze.so.  "Make"ing this monolith though involves a series of .o files being built at the same time.  SeaBreezeWrapper.o and SeaBreeze.o among others.  I can't statically link to either of these getting the error "project1.lpr(22,0) Error: Error while linking."   %)  The .a also will not link statically.  These are intended as interface "wrappers."  One is older and one is new.

Both LoadLibrary and SafeLoadLibrary return 0 with no other diagnostic info available when trying to load the .so.  In a hail mary attempt, I tried loading the .o as well and that clearly doesn't work.   

I'll just mention again that the interface (built with VS2013) works fine in Windows.  In that environment, only the one dll (equivalent of the .so) is created.  I consider the original authors to be quite good as the use code base is compiled under linux, unix, Windows and I believe Mac.  (This is the code I can run successfully with the demo programs shipped with Seabreeze.)

Ah yes, I also tried tracing into dynlibs.  That's essentially a call into someplace invisible.

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Trying to link to 3rd party, c, .so.
« Reply #21 on: December 20, 2017, 11:17:31 pm »
It occurred to me that one thing I haven't mentioned is that the library is a single file, libseabreeze.so.  "Make"ing this monolith though involves a series of .o files being built at the same time.  SeaBreezeWrapper.o and SeaBreeze.o among others.  I can't statically link to either of these getting the error "project1.lpr(22,0) Error: Error while linking."   %)  The .a also will not link statically.  These are intended as interface "wrappers."  One is older and one is new.

In your header file, SeaBreezeWrapper is a C++ class that also gets compiled along with the C function declarations if you compile with a C++ compiler; otherwise, only the C interface gets compiled. You can only call the C functions, not the C++ stuff. Ignore the .o and .a files for now - those are irrelevant to your LoadLibrary problem.

I've been working with and creating dynamic libraries on macOS, Windows and Linux for years and this stuff works flawlessly with Pascal. I don't have any Linux gadget boards, but I can't imagine that there would be anything out of the ordinary about LoadLibrary there.

Edit: Maybe start with something that's known to Pascal programmers as working. Eg, try building the ndfd library from Part 2 of the link I gave above and calling it from Pascal.
« Last Edit: December 20, 2017, 11:19:02 pm by Phil »

jbmckim

  • Full Member
  • ***
  • Posts: 144
Re: Trying to link to 3rd party, c, .so.
« Reply #22 on: December 21, 2017, 04:05:36 am »
Maybe I sorted the IFDEFs incorrectly but this:
T
Code: Pascal  [Select][+][-]
  1. seabreeze_open_spectrometer = function (iWorking:Integer; errorcode:PInteger):Integer; cdecl; external '/home/pi/Documents/ScratchProjects/libseabreeze.so';

throws this error on compile:

Code: Pascal  [Select][+][-]
  1. unit1.pas(42,98) Error: Procedure directive "EXTERNAL" not allowed in procvar declaration

 

TinyPortal © 2005-2018