shared-object.scm 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Mike Sperber, Marcus Crestani
  3. ; This is file shared-object.scm.
  4. ; Dynamically load external object files.
  5. (define-record-type shared-object :shared-object
  6. (make-shared-object name complete-name? c-handle)
  7. shared-object?
  8. (name shared-object-name)
  9. ;; says whether the OS should add a system-dependent extension
  10. ;; (such as .so or .dll) or do some other such transformation
  11. (complete-name? shared-object-complete-name?)
  12. (c-handle shared-object-c-handle
  13. set-shared-object-c-handle!))
  14. (define-record-discloser :shared-object
  15. (lambda (shared-object)
  16. (list 'shared-object
  17. (shared-object-name shared-object))))
  18. ;; Doing better would be quite a bit of work: Each shared object would
  19. ;; need to maintain a population of addresses derived from it, so we
  20. ;; can avoid ordering problems. Morever, the filename specified might
  21. ;; be relative, causing further problems.
  22. ;; On the other hand, the high-level code might have a better approach
  23. ;; to this, so we don't forbid dumping on these.
  24. (define-record-resumer :shared-object #t)
  25. (define (open-shared-object name complete-name?)
  26. (let ((shared-object (make-shared-object name
  27. complete-name?
  28. (external-dlopen (x->os-byte-vector name)
  29. complete-name?))))
  30. (add-finalizer! shared-object close-shared-object)
  31. shared-object))
  32. (define (close-shared-object shared-object)
  33. (let ((c-handle (shared-object-c-handle shared-object)))
  34. (if c-handle
  35. (begin
  36. (external-dlclose c-handle)
  37. (set-shared-object-c-handle! shared-object #f)))))
  38. (define-record-type shared-object-address :shared-object-address
  39. (make-shared-object-address object
  40. name
  41. value)
  42. shared-object-address?
  43. (object shared-object-address-object)
  44. (name shared-object-address-name)
  45. (value shared-object-address-value))
  46. (define-record-discloser :shared-object-address
  47. (lambda (shared-object-address)
  48. (list 'shared-object-address
  49. (shared-object-address-object shared-object-address)
  50. (shared-object-address-name shared-object-address))))
  51. (define-record-resumer :shared-object-address #f)
  52. (define (shared-object-address shared-object name)
  53. (make-shared-object-address shared-object
  54. name
  55. (external-dlsym (shared-object-c-handle shared-object)
  56. (os-string->byte-vector
  57. (call-with-os-string-text-codec
  58. utf-8-codec
  59. (lambda ()
  60. (x->os-string name)))))))
  61. (define (shared-object-address-or-false shared-object name)
  62. (guard (c (else #f))
  63. (shared-object-address shared-object name)))
  64. ;; This simply calls a C function with no parameters and no return
  65. ;; value. It's typically for calling the initialization function; we
  66. ;; can't use any of the regular external-calling mechanisms because
  67. ;; they expect a s48_value return value, where the initialization
  68. ;; function has void.
  69. (define (call-shared-object-address s-o-address)
  70. (external-call-thunk (shared-object-address-value s-o-address)))
  71. (import-lambda-definition-2 external-dlopen (name generate-name?)
  72. "shared_object_dlopen")
  73. (import-lambda-definition-2 external-dlsym (handle name)
  74. "shared_object_dlsym")
  75. (import-lambda-definition-2 external-dlclose (shared-object)
  76. "shared_object_dlclose")
  77. (import-lambda-definition-2 external-call-thunk (address)
  78. "shared_object_call_thunk")