[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