Hello.
I have problem to access methods from a C library. For FreeBSD, the methods cannot be accessed (but ok for Linux and Windows). In FreeBSD, LoadLibrary(aac.so) is working but all GetProcAdress() for each method fail. I already ask help in FreeBSD forum : https://forums.freebsd.org/threads/55305/ But without luck. Could it be that something is wrong with mangle-name of exported methods of the library in FreeBSD ? Does anybody have a idea why GetProcAdress() fail in FreeBSD (but ok for Linux and Windows) ? Or must the library-code be compiled with some special instructions for fpc ? Every comment or light is highly welcome (tips, must-know, etc,...). PS: A solution is highly expected because there are other libraries, with same problems in FreeBSD, that wait to be used by fpc-FreeBSD. Many thanks. Fre;D |
Am 14.03.2016 16:16 schrieb "fredvs" <[hidden email]>: You could check with objdump or nm what the exported symbols look like in the library. There are some systems that export C functions with a leading '_' for example. Regards, _______________________________________________ fpc-pascal maillist - [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal |
> You could check with objdump or nm what the exported symbols look like in the library. There are some systems that export > C functions with a leading '_' for example.
Hello Sven and thanks for answer. Here result of nm on FreeBSD 64. ![]() But it seems that the exported functions have the same names as for Linux or Windows (like "mp4ff_open_read", "mp4ff_close", ...) Or do you see a "special" exported name ? Many thanks. |
In reply to this post by fredvs
On Mo, 2016-03-14 at 08:15 -0700, fredvs wrote:
> Hello. > > I have problem to access methods from a C library. > > For FreeBSD, the methods cannot be accessed (but ok for Linux and Windows). > > In FreeBSD, LoadLibrary(aac.so) is working but all GetProcAdress() for each > method fail. > Does anybody have a idea why GetProcAdress() fail in FreeBSD (but ok for > Linux and Windows) ? > > Or must the library-code be compiled with some special instructions for fpc > ? > > Every comment or light is highly welcome (tips, must-know, etc,...). It would be helpful to see the code fragments in question. The declaration of the external functions if any and the code calling LoadLibrary() and GetProcAddress(). -- Marc Santhoff <[hidden email]> _______________________________________________ fpc-pascal maillist - [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal |
> it would be helpful to see the code fragments in question.
> The declaration of the external functions if any and the code calling > LoadLibrary() and GetProcAddress(). Hello Mark and thanks for help. Here declaration to load-getprocess: ----------------------------------------------------- var mp4ff_open_read : function(f : p_mp4ff_callback_t) : mp4ff_t; cdecl; libpointer : {$IFDEF MSWINDOWS}longword{$ELSE}{$IFDEF CPU32}longword{$ELSE}PtrInt{$ENDIF}{$ENDIF}; ... libpointer := DynLibs.SafeLoadLibrary(PChar(mp4ff)); -> OK for FreeBSD64 too;-) Pointer(mp4ff_open_read) := GetProcAddress(hMp4ff, pchar('mp4ff_open_read')); -> Here always = nil for FreeBSD 64 ;-( (but ok for Linux + Windows) ... ----- Thanks. Fre;D PS: I have the same problem for other libraries in FreeBSD 64 -> GetProcAddress() fail. PS2: It appends for some libraries in FreeBSD64, not all. |
On Do, 2016-03-17 at 04:27 -0700, fredvs wrote:
> > it would be helpful to see the code fragments in question. > > The declaration of the external functions if any and the code calling > > LoadLibrary() and GetProcAddress(). > > Hello Mark and thanks for help. > > Here declaration to load-getprocess: > ----------------------------------------------------- > var > mp4ff_open_read : function(f : p_mp4ff_callback_t) : mp4ff_t; cdecl; > libpointer : {$IFDEF MSWINDOWS}longword{$ELSE}{$IFDEF > CPU32}longword{$ELSE}PtrInt{$ENDIF}{$ENDIF}; > ... > > libpointer := DynLibs.SafeLoadLibrary(PChar(mp4ff)); -> OK for FreeBSD64 > too;-) > > Pointer(mp4ff_open_read) := > GetProcAddress(hMp4ff, pchar('mp4ff_open_read')); -> Here always = > nil for FreeBSD 64 ;-( (but ok for Linux + Windows) > ... > ----- When following the procedure calls I find: <dynlibs.pas> Function GetProcAddress(Lib : TlibHandle; const ProcName : AnsiString) : Pointer; begin Result:=GetProcedureAddress(Lib,Procname); end; </dynlibs.pas> Next is: <dynlibs.inc> Function GetProcedureAddress(Lib : TLibHandle; const ProcName : AnsiString) : Pointer; begin Result:=dlsym(lib,pchar(ProcName)); end; </dynlibs.inc> Okay, man page says: http://www.freebsd.org/cgi/man.cgi?query=dlsym&apropos=0&sektion=0&manpath=FreeBSD+10.2-RELEASE&arch=default&format=html You could do some things, like trying to use the special handle RTLD_NEXT, or and much more important, call dlerror() after the failing dlsym(). It should tell _why_ the call failed. > PS: I have the same problem for other libraries in FreeBSD 64 -> > GetProcAddress() fail. > PS2: It appends for some libraries in FreeBSD64, not all. Intresting. I know there are differences in the systems dlopen() and another similar variant installed by libtool, found in libbtdl regarding to my notes. Dunno if it matters. Libtools implementation does differentiate between OSs by itself (at compile time). Cold be a source of confusion... -- Marc Santhoff <[hidden email]> _______________________________________________ fpc-pascal maillist - [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal |
> When following the procedure calls I find:
... Hello Mark. Thanks for your light. Huh, yes, IMO, there is something strange in dlsym/FreeBSD. And asking something about C library/compiler is extremely sensible there on FreeBSD forum. (FreeBSD needs 8 (!) different C compilers (clang, c++, CC, cc, cpp, ...) to compile himself). OK, the solution is to wait for a solution. Many thanks. Fre;D |
On Fr, 2016-03-18 at 16:34 -0700, fredvs wrote:
> > When following the procedure calls I find: > ... > > Hello Mark. > > Thanks for your light. > > Huh, yes, IMO, there is something strange in dlsym/FreeBSD. Would you mind telling the result of dlerror()? > And asking something about C library/compiler is extremely sensible there on > FreeBSD forum. > (FreeBSD needs 8 (!) different C compilers (clang, c++, CC, cc, cpp, ...) to > compile himself). Not really. Since c++ is the same compiler as (g)cc, cpp is the C ppreprocessor an CC is mostly only used as a variable name in Makefiles and shell skripts set to the right compiler, that is clearly wrong. There are in fact different C compilers which are all able to compile C or C++. There is actually the system compiler, which has been gcc and will be or is already clang. Some ports require newer versions of gcc, so sometimes there are two or three of them installed. But that's it, AFAIK. Look: marc@puma:/home/marc > cc -v Using built-in specs. Target: amd64-undermydesk-freebsd Configured with: FreeBSD/amd64 system compiler Thread model: posix gcc version 4.2.1 20070831 patched [FreeBSD] marc@puma:/home/marc > gcc -v Using built-in specs. Target: amd64-undermydesk-freebsd Configured with: FreeBSD/amd64 system compiler Thread model: posix gcc version 4.2.1 20070831 patched [FreeBSD] marc@puma:/home/marc > CC -v Using built-in specs. Target: amd64-undermydesk-freebsd Configured with: FreeBSD/amd64 system compiler Thread model: posix gcc version 4.2.1 20070831 patched [FreeBSD] marc@puma:/home/marc > c++ -v Using built-in specs. Target: amd64-undermydesk-freebsd Configured with: FreeBSD/amd64 system compiler Thread model: posix gcc version 4.2.1 20070831 patched [FreeBSD] marc@puma:/home/marc > cpp --version cpp (GCC) 4.2.1 20070831 patched [FreeBSD] Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. All the same. ;) Only that one differs: marc@puma:/home/marc > clang -v FreeBSD clang version 3.0 (tags/RELEASE_30/final 145349) 20111210 Target: x86_64-unknown-freebsd9.0 Thread model: posix You can try looking at the manual pages, type in "man cc" and the other names. -- Marc Santhoff <[hidden email]> _______________________________________________ fpc-pascal maillist - [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal |
> Would you mind telling the result of dlerror()?
OK, I will follow your tips. Write you later with the result. > There are in fact different C compilers which are all able to compile C or C++. Yes and nearly all that compilers are the same (why not use sym-link?) -> "Why not use sym-link in place of copy 8x the same compiler (+- 8 megas) with different name " -> Dont ask this to FreeBSD forum -> It is sensible. (I already try) -> "Why, in the script to create-compile the kernel of FreeBSD, different compilers are used (that are the same in fact). Would it not be simpler to use only one compiler ? " -> Dont ask this to FreeBSD forum -> It is sensible. (I already try) PS: I will become totally fan of FreeBSD when the C-war will end and when it will be easy to recompile the kernel (with only one compiler). Many thanks for your excellent tips Marc. Write you later. Fre;D |
Hello Marc.
Huh, I have a dummy question... How do you use dlopen(), dlsym() and dlerror() ? On console, with -> fred@freebsd> dlopen('/root/mylib.so') Result = "Illegal command name..." > call dlerror() after the failing dlsym(). It should tell _why_ the call failed. Re-huh..., it should be a great plus if a dlerror() was implemented in fpc too. But maybe I am missing something, maybe dlopen(), dlsym() and dlerror() can be done by pascal code (and not via console, like I try). Thanks. Fre;D |
On 03/19/2016 07:49 PM, fredvs wrote:
> Hello Marc. > > Huh, I have a dummy question... > > How do you use dlopen(), dlsym() and dlerror() ? > > On console, with -> > > fred@freebsd> dlopen('/root/mylib.so') > > Result = "Illegal command name..." > >> call dlerror() after the failing dlsym(). It should tell _why_ the call >> failed. > Re-huh..., it should be a great plus if a dlerror() was implemented in fpc > too. > > But maybe I am missing something, maybe dlopen(), dlsym() and dlerror() can > be done by pascal code (and not via console, like I try). > never tried the latter, but it appears they are not on your system ;-) Now, I don't know where exactly these functions are declared (in which unit, that is), but for debugging purposes, just add Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external; Function dlclose(handle: Pointer): cint; cdecl; external; Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external; Function dlerror: PChar; cdecl; external; Somewhere in your code before you call them. -- Ewald _______________________________________________ fpc-pascal maillist - [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal |
> dlopen, dlsym and dlerror are *functions*, not console commands. Well, I
> never tried the latter, but it appears they are not on your system ;-) > Now, I don't know where exactly these functions are declared (in which > unit, that is), but for debugging purposes, just add > Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external; > Function dlclose(handle: Pointer): cint; cdecl; external; > Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external; > Function dlerror: PChar; cdecl; external; > Somewhere in your code before you call them. Ooops, thanks for answer but now I am completely loosed... ;-( So those functions can be used in fpc code? If so, must a library be loaded to access that functions (and what library)? Or are those functions defined in a fpc unit ? I am in the dark. Fre;D |
In reply to this post by Ewald-2
In our previous episode, Ewald said:
> > Re-huh..., it should be a great plus if a dlerror() was implemented in fpc > > too. > > > > But maybe I am missing something, maybe dlopen(), dlsym() and dlerror() can > > be done by pascal code (and not via console, like I try). > > > dlopen, dlsym and dlerror are *functions*, not console commands. Well, I > never tried the latter, but it appears they are not on your system ;-) > > Now, I don't know where exactly these functions are declared (in which > unit, that is), but for debugging purposes, just add > > Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external; > Function dlclose(handle: Pointer): cint; cdecl; external; > Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external; > Function dlerror: PChar; cdecl; external; > > Somewhere in your code before you call them. ... or use unit dl. _______________________________________________ fpc-pascal maillist - [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal |
On 03/19/2016 08:53 PM, Marco van de Voort wrote:
> In our previous episode, Ewald said: >>> Re-huh..., it should be a great plus if a dlerror() was implemented in fpc >>> too. >>> >>> But maybe I am missing something, maybe dlopen(), dlsym() and dlerror() can >>> be done by pascal code (and not via console, like I try). >>> >> dlopen, dlsym and dlerror are *functions*, not console commands. Well, I >> never tried the latter, but it appears they are not on your system ;-) >> >> Now, I don't know where exactly these functions are declared (in which >> unit, that is), but for debugging purposes, just add >> >> Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external; >> Function dlclose(handle: Pointer): cint; cdecl; external; >> Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external; >> Function dlerror: PChar; cdecl; external; >> >> Somewhere in your code before you call them. > ... or use unit dl. I knew they were in some unit somewhere ;-) Thanks for the pointer! -- Ewald _______________________________________________ fpc-pascal maillist - [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal |
In reply to this post by fredvs
On 03/19/2016 08:29 PM, fredvs wrote:
>> dlopen, dlsym and dlerror are *functions*, not console commands. Well, I >> never tried the latter, but it appears they are not on your system ;-) >> Now, I don't know where exactly these functions are declared (in which >> unit, that is), but for debugging purposes, just add >> Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; >> external; >> Function dlclose(handle: Pointer): cint; cdecl; external; >> Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external; >> Function dlerror: PChar; cdecl; external; >> Somewhere in your code before you call them. > Ooops, thanks for answer but now I am completely loosed... ;-( > > So those functions can be used in fpc code? > If so, must a library be loaded to access that functions (and what library)? > Or are those functions defined in a fpc unit ? See Marco's answer. So instead of using the above declarations, a simple `Uses dl;` should do the trick. As to how to use them, now you do something like this: X:= GetProcedureAddress(...); Y:= GetProcedureAddress(...); Z:= GetProcedureAddress(...); When one of these fails, a nil pointer is returned. dlerror will give you more info on what failed where. So, if you know X returns nil for some-yet-to-be-determined-reason, place the dlerror immediately after that: X:= GetProcedureAddress(...); WriteLn(dlerror); Y:= GetProcedureAddress(...); Z:= GetProcedureAddress(...); Of course, you could choose to do something like this if you do not know which call exactly fails: X:= GetProcedureAddress(...); If X = nil Then WriteLn('Z: ', dlerror); Y:= GetProcedureAddress(...); If Y = nil Then WriteLn('Y: ', dlerror); Z:= GetProcedureAddress(...); If Z = nil Then WriteLn('Z: ', dlerror); It is really nothing more than a function call, quite similar to fpGetErrNo. > I am in the dark. Being in the dark is positive, as one can always turn on the lights :-) -- Ewald _______________________________________________ fpc-pascal maillist - [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal |
@ Marco and Marc thanks for help.
Sorry I do not have easy internet connection so I worked by my side. I will try your tips. By the way, here are my investigations: ____________________________________ Hello. Ok, ok, understood and wow. Added in code: Function dlopen(filename: PChar; flags: cint): Pointer; cdecl; external; Function dlclose(handle: Pointer): cint; cdecl; external; Function dlsym(handle: Pointer; Name: PChar): Pointer; cdecl; external; Function dlerror: PChar; cdecl; external; and, magic, it works. ;-) Now the result: In code: procedure loadmylib(lib : pchar); var ap1, ap2, ap3 : pointer; ' begin /// FreeBSD functions: ap1 := dlopen(Pchar(lib), 0); if ap1 <> nil then writeln('dlopen() is OK') else writeln('dlopen() is NOT OK') ; ap2 := dlsym(ap1, Pchar('mp4ff_open_read'); if ap2 <> nil then writeln('dlsym() is OK') else writeln('dlsym() is NOT OK') ; writeln(dlerror()); end; ---> result: writeln('dlopen() is OK') writeln('dlsym() is OK') _ (no error) -------------------------------------- Now with DynLibs: procedure loadmylib(lib : pchar); var ap1: pointer; hn : integer; ' begin /// with dynlibs hn := dynlibs.loadlibrary(Pchar(lib)); if hn <> 0 then writeln('loadlibrary() is OK') else writeln('loadlibrary() is NOT OK') ; ap1 := getprocedureaddress(hn, Pchar('mp4ff_open_read'); if ap1 <> nil then writeln('getprocedureaddress() is OK') else writeln('getprocedureaddress() is NOT OK') ; end; --> result: loadlibrary() is OK getprocedureaddress() is NOT OK ............ Conclusion: Maybe getprocedureaddress() has problems. PS: Other tips are welcome. Fre;D |
OOOps, in previos mail:
Thanks to Ewald, Marco and Marc. Fre;D |
In reply to this post by fredvs
Just quick before they cut the signal...
Could dlsym(ap1, Pchar('mp4ff_open_read') be used in place of getprocedureaddress(hn, Pchar('mp4ff_open_read') ? Because, if dlsym() works, maybe replacing all getprocedureaddress() with dlsym() will work? And can loadlibrary() be used by dlsym() ( or dlsym() needs dlopen() ) ? Thanks. Fre;D |
Re-hello (and last for tonight).
Yep, yep, yep. Replacing all GetProcedureAdress() with dlsym() DOES THE TRICK ! ;-) (but dlopen() is needed in place of Loadlibrary()) Excellent tip. Many, many, many thanks for help. (And, maybe, a check for DynLibs.GetProcedureAdress() is needed for FreeBSD). And re-thanks for your bright light. PS: This is a great victory who will solve (I hope) other library-related problems. PS2: Are there limitations of using dlsym() vs GetProcedureAdress() ? PS3: If dlsym() is cross-platform too, should I update all my codes that use GetProcedureAdress() ? Fre;D |
Am 20.03.2016 00:57 schrieb "fredvs" <[hidden email]>: LoadLibrary and GetProcedureAddress internally use dlopen and dlsym respectively on Unix-like platforms. So it might be that either LoadLibrary or GetProcedureAddress calls its respective internal function incorrectly on FreeBSD and that needs to be fixed then. Regards, _______________________________________________ fpc-pascal maillist - [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal |
Free forum by Nabble | Edit this page |