* * *

Author Topic: LoadLibrary error.  (Read 820 times)

helmi

  • New member
  • *
  • Posts: 10
LoadLibrary error.
« on: April 10, 2017, 07:21:25 pm »
I have successfully LoadLibrary dynamic library but I get error 'Access violation' when try execute the function.

OS: Mac OS 10.12.4
Lazarus: 1.6.4

Code: Pascal  [Select]
  1. TMyFunc=function (aInt:Integer):Integer; StdCall;
  2. ...
  3. .
  4. MyFunc:=TMyFunc(GetProcedureAddress(MyLibC, 'Test'));
  5. MyFunc(5); //error when I enable this code
  6.  

Phil

  • Hero Member
  • *****
  • Posts: 2043
Re: LoadLibrary error.
« Reply #1 on: April 10, 2017, 07:26:58 pm »
I have successfully LoadLibrary dynamic library but I get error 'Access violation' when try execute the function.

OS: Mac OS 10.12.4
Lazarus: 1.6.4

Usually C libraries on OS X and Linux will use cdecl calling convention, not stdcall.

You might find this series of articles on dynamic libraries helpful:

https://macpgmr.github.io

helmi

  • New member
  • *
  • Posts: 10
Re: LoadLibrary error.
« Reply #2 on: April 10, 2017, 07:42:34 pm »
Thanks for the link. I have changed it but stil get same error.

Code: Pascal  [Select]
  1. TMyFunc=function (aInt:Integer):Integer; Cdecl;

Phil

  • Hero Member
  • *****
  • Posts: 2043
Re: LoadLibrary error.
« Reply #3 on: April 10, 2017, 07:48:00 pm »
Thanks for the link. I have changed it but stil get same error.

Code: Pascal  [Select]
  1. TMyFunc=function (aInt:Integer):Integer; Cdecl;

You did load the library first, right? You don't show that code.

In general, it's a good idea to use types from the FPC ctypes.pp unit so you know that what you're declaring matches what's in the C code.

Thaddy

  • Hero Member
  • *****
  • Posts: 3434
Re: LoadLibrary error.
« Reply #4 on: April 10, 2017, 08:39:08 pm »
Apart from that, the external function name is case sensitive.
Code: Pascal  [Select]
  1. TMyFunc=function (aInt:cint):Integer; cdecl;
  2. ...
  3. .
  4. MyFunc:=TMyFunc(GetProcedureAddress(MyLibC, 'Test'));  
  5. // maybe  'test'? or 'TEST'? or even '_test': must be exact....
  6. // Also the library name itself is case sensitive: MyLibC := 'mylibc.so'?
  7. // check the result: did the call to getprocedureaddress succeed?
  8. if MyFunc <> nil then  // or assert(myfunc <>nil,' Could not find procedure Test'); with {$assertions on}.
  9.    MyFunc(5); //error when I enable this code
  10.  

See http://www.freepascal.org/docs-html/rtl/dynlibs/getprocedureaddress.html
« Last Edit: April 10, 2017, 08:48:56 pm by Thaddy »

helmi

  • New member
  • *
  • Posts: 10
Re: LoadLibrary error.
« Reply #5 on: April 11, 2017, 10:37:52 am »
Sorry, my mistake. I loaded another dynamic link file and call a function that not exist in the library. But can't load my own test library.

c++ code
#include <stdio.h>

extern "C" {
   int __cdecl function1(int t1)
   {
      return 1;
    }
}

compile with: g++ -shared -o mylib.dynlib test.cpp

I copied the file to /tmp

Code: Pascal  [Select]
  1. MyLibC := LoadLibrary('/tmp/mylib.dynlib');
  2.  
  3. if MyLibC = dynlibs.NilHandle then
  4.   wrriteln('not loaded');
  5. else
  6.   wrriteln('loaded');
  7. end
  8.  

Thaddy

  • Hero Member
  • *****
  • Posts: 3434
Re: LoadLibrary error.
« Reply #6 on: April 11, 2017, 12:20:18 pm »
What rights does the library have?

rvk

  • Hero Member
  • *****
  • Posts: 2417
Re: LoadLibrary error.
« Reply #7 on: April 11, 2017, 02:11:04 pm »
Code: Pascal  [Select]
  1. MyLibC := LoadLibrary('/tmp/mylib.dynlib');
  2.  
  3. if MyLibC = dynlibs.NilHandle then
  4.   wrriteln('not loaded');
  5. else
  6.   wrriteln('loaded');
  7. end
  8.  
This isn't really the code you have in your program, do you ???

  • wrriteln() isn't anything.
  • You have ; after the first wrriteln so the else doesn't do anything (or is not for the previous if).
  • The end doesn't match any beginning.

Please, ONLY post real code.
« Last Edit: April 11, 2017, 02:13:14 pm by rvk »

Thaddy

  • Hero Member
  • *****
  • Posts: 3434
Re: LoadLibrary error.
« Reply #8 on: April 11, 2017, 03:09:13 pm »
This is getting ridiculous:
We point out what to do and he keeps posting rubbish.
- CHECK if the names are EXACTLY as on disk.
- CHECK if loadlibrary works in your code (as per my example)
- CHECK if getprocedureaddress works in your code (as per my example)
- MAKE SURE the library is in a path and in a path with sufficient rights
- MAKE SURE the library has executable rights. (this depends on platform but just to make sure)

You seem to miss the point completely that we are trying to help.... RvK is right about that.
Normally a library should be in a lib directory and not somewhere in the wild (ok for debugging), for one. E.g.: Is it in /usr/lib/ or in/usr/local/lib? Then you don't need a full path..
You seem to like CamelCase: don't do that in Linux file handling, make everything lowercase (for beginners).

Oh, first do something right and give us code.
 
« Last Edit: April 11, 2017, 03:11:47 pm by Thaddy »

helmi

  • New member
  • *
  • Posts: 10
Re: LoadLibrary error.
« Reply #9 on: April 11, 2017, 03:31:58 pm »
The file located at /tmp/mylib.dynlib and chmod the file with a+x. Also have tried put the file in /opt/local/lib.

Code: Pascal  [Select]
  1. uses
  2.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, dynlibs;
  3.  
  4. type
  5. { TForm1 }
  6.   TMyFunc=function (aInt:Integer):Integer; cdecl;
  7.  
  8. var
  9.   Form1: TForm1;
  10.   MyLibC: TLibHandle;
  11.   FuncResult: string;
  12.   MyFunc: TMyFunc;
  13.  
  14. implementation
  15.  
  16. { TForm1 }
  17.  
  18. procedure TForm1.Button1Click(Sender: TObject);
  19. begin
  20.   MyLibC := LoadLibrary('/tmp/mylib.dynlib');
  21.  
  22.   if MyLibC = dynlibs.NilHandle then
  23.      begin
  24.           //not loaded.
  25.           Memo1.Append('Not Loaded');
  26.      end
  27.   else
  28.   begin
  29.       Memo1.Append('Loaded');
  30.       MyFunc:=TMyFunc(GetProcedureAddress(MyLibC, 'Test'));
  31.       MyFunc(5);
  32.    end
  33. end;
  34.  

rvk

  • Hero Member
  • *****
  • Posts: 2417
Re: LoadLibrary error.
« Reply #10 on: April 11, 2017, 03:41:04 pm »
The file located at /tmp/mylib.dynlib and chmod the file with a+x. Also have tried put the file in /opt/local/lib.
That's better.

And you say you are getting 'Not Loaded' ??

I don't have OSX but what bit-versions are you using for Lazarus and g++?
If you compiled the dynlib in 64 bit and your Lazarus is 32 bit, they don't match.

I only see the 32 bit version of Lazarus for OSX so make sure your g++ also compiles in 32 bit.
Maybe you can check with lipo -info /tmp/mylib.dynlib what version is compiled.


helmi

  • New member
  • *
  • Posts: 10
Re: LoadLibrary error. SOLVED
« Reply #11 on: April 11, 2017, 04:12:34 pm »
 I have installed using suggested by Lazarus website. Lazarus 1.6.4 (fpc 3.0.2) i386 darwin carbon. my dynamic library is 64 bit. I recompile my c++ code with flag -m32

I have successfully load the library and call the function. Thank You.

Phil

  • Hero Member
  • *****
  • Posts: 2043
Re: LoadLibrary error. SOLVED
« Reply #12 on: April 11, 2017, 04:15:29 pm »
I have successfully load the library and call the function. Thank You.

Note that the extension for dynamic libraries on OS X is .dylib, not .dynlib. There are no files with a .dynlib extension on a Mac.

g++ is just a symlink to clang on Mac. clang is the C frontend you should be working with. OS X no longer uses GCC compilers.


helmi

  • New member
  • *
  • Posts: 10
Re: LoadLibrary error. SOLVED
« Reply #13 on: April 11, 2017, 04:29:11 pm »
I have successfully load the library and call the function. Thank You.

Note that the extension for dynamic libraries on OS X is .dylib, not .dynlib. There are no files with a .dynlib extension on a Mac.

g++ is just a symlink to clang on Mac. clang is the C frontend you should be working with. OS X no longer uses GCC compilers.

Thank you. My mistake after a lot of typing to test it.

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus