[Ecls-list] generated shared library does not contain the defined function

Ala'a Mohammad amalawi at gmail.com
Mon May 20 13:36:23 UTC 2013


I mistakenly assumed that 'defined protocol' was for when linking with
libecl. and thought that the c:build-shared-library was similar to
LispWorks delivered shared libraries (see the attached example that I was
trying to port from LW).

So now I need to execute that defined protocol, and then:
- load my library (my CL library)
- define a result object with cl_object.
- create a CL array object via 'si_make_array'
- fill the created array with the data.
- call the the function sum_array and store the result in the result object.

Thanks to all for the help,

Ala'a


LW shared library example:

---- example.lisp
(in-package "CL-USER")

(fli:define-foreign-callable ("say_hello" :result-type :void)
    ()
  (write-line "Hello From Shared Library.")
  (force-output)
  (values))

(fli:define-foreign-callable ("square" :result-type :int)
    ((num :int))
  (* num num))

(fli:define-foreign-callable ("sum_array" :result-type :int)
    ((nums (:c-array :int 10))
     (size :int))
  (loop for i from 0 below size
        summing (fli:foreign-aref nums i)))

(fli:define-foreign-callable ("sum_dyn_array" :result-type :int)
    ((dyn_nums (:pointer :int))
     (size :int))
  (loop repeat size
        summing (fli:dereference dyn_nums :type :int)
        do (fli:incf-pointer dyn_nums)))



------ deliver.lisp ------

(in-package "CL-USER")

(load-all-patches)

(compile-file (current-pathname "example.lisp")  :load t)

(deliver nil
         (current-pathname "lw-shared" nil)
         5
         :dll-exports '("square" "say_hello" "sum_array" "sum_dyn_array"))


------ command line - generate shared library  --------

lispworks-6-1-0-x86-linux -build deliver.lisp



------ try.c ------

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

void (*say_hello)(void);
int (*square)(int);
int (*sum_array)(int *array, int size);
int (*sum_dyn_array)(int *array, int size);

int main(int argc, char **argv)
{
  void *handle;
  int index;
  int total_sum = 0;
  int number = 10;
  int nums[10] = {17, 2, 0, 0, 4, 5, 6, 9, 9, 15};
  int *dyn_nums;
  int dyn_array_size = 20;

  handle = dlopen("/tmp/lw-shared.so", RTLD_LAZY);
  if (!handle) {
    fprintf(stderr, "Failed to load shared library:\n %s\n", dlerror());
    exit(1);
  }

  say_hello = dlsym(handle, "say_hello");
  if (!say_hello) {
    fprintf(stderr, "Failed to find symbol:\n %s\n",
            dlerror());
    exit(1);
  }
  (*say_hello)();

  square = dlsym(handle, "square");
  if (!square) {
    fprintf(stderr, "Failed to find symbol:\n %s\n",
            dlerror());
    exit(1);
  }
  printf("Square of %i is %i\n", number, (*square)(number));

  sum_array = dlsym(handle, "sum_array");
  if (!sum_array) {
    fprintf(stderr, "Failed to find symbol:\n %s\n",
            dlerror());
    exit(1);
  }
  printf("sum of nums array from LW is %i\n",(*sum_array)(nums, 10));

  for(index=0; index<10; ++index){
    total_sum += nums[index];
  }
  printf("sum of nums array from C is %i\n", total_sum);


  sum_dyn_array = dlsym(handle, "sum_dyn_array");
  if (!sum_dyn_array) {
    fprintf(stderr, "Failed to find symbol:\n %s\n",
            dlerror());
    exit(1);
  }

  dyn_nums = malloc(dyn_array_size * sizeof(int));
  if (!dyn_nums) {
    printf("Error allocating memory!\n");
    return 1;
  }

  for(index=0; index<dyn_array_size; ++index){
    dyn_nums[index] = index;
  }

  printf("sum of dyn_nums array from LW is %i\n",(*sum_dyn_array)(dyn_nums,
dyn_array_size));

  total_sum = 0;
  for(index=0; index<dyn_array_size; ++index){
    total_sum += dyn_nums[index];
  }
  printf("sum of dyn_nums array from C is %i\n", total_sum);

  free(dyn_nums);

  return 0;
}

------ command line - compile try.c  --------
gcc try.c -o try -ldl -lpthread



On Mon, May 20, 2013 at 1:08 AM, Juan Jose Garcia-Ripoll <
juanjose.garciaripoll at gmail.com> wrote:

> On Mon, May 13, 2013 at 12:33 PM, Ala'a Mohammad <amalawi at gmail.com>wrote:
>
>> This is my first try at ECL, and need help in figuring out what is
>> missing. I had tried googling for similar examples but did not found one
>> that demoed what i wanted.
>>
>
> There are many examples out there how to call Common Lisp functions.
> Indeed many in this very same mailing list explain how to call cl_boot(),
> ecl_read_from_cstring(), cl_funcall() and friends. Directly calling a
> Common Lisp function compiled by you by name is not recommended.
>
>
>> (proclaim '(si::c-export-fname sum-arary))
>>
>
> In order to have compile-time side effects you need to fix the name and use
> (eval-when (:compile-toplevel)
>  (proclaim '(si::c-export-fname sum-array)))
>
>   // summ-array
>>   ////demo_sum_array  = dlsym(libhandle,"demo_sum_array");
>>   demo_sum_array  = dlsym(libhandle,"L1sum_array");
>>   if(demo_sum_array == NULL) {
>>     /* ERROR HANDLING */
>>     fprintf(stderr, "%s\n", dlerror());
>>     exit(1);
>>   }
>>
>
> Broken, broken, broken. ECL has to be bootstrapped before calling any
> function. This involves a well defined protocol that starts by calling
> cl_boot() with two arguments and, optionally, registering any additional
> threads from which code may be invoked. Then you can start using Common
> Lisp functions and objects.
>
> Juanjo
>
> --
> Instituto de Física Fundamental, CSIC
> c/ Serrano, 113b, Madrid 28006 (Spain)
> http://juanjose.garciaripoll.googlepages.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/ecl-devel/attachments/20130520/edb7042a/attachment.html>


More information about the ecl-devel mailing list