-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 13-Feb-07, at 1:18 AM, James Long wrote:
There's got to be something I'm missing, has anyone else gotten this to work? Or does anyone see anything wrong with how I'm compiling the dll (the loading part is relatively simple and I doubt the problem is in there)?
Yes. What is missing is the *initialization* of the Gambit-C runtime system (all the tables used by Gambit-C, the memory manager, the I/O subsystem, etc). This is done with a call to ___setup(...). The initialization must happen before the first call to any function your Scheme DLL is exporting. The best approach is probably to call ___setup(...) when the code is loaded (i.e. the call ___setup(...) should be in the DllMain function). It is good style to call ___cleanup() when the DLL is unloaded.
I've copied below the code that works for me. I'm using MinGW. Small variations may be needed to the makefile for Cygwin and Microsoft's compiler.
Let me know if this works with .NET .
Marc
********************************************************************** # File: "makefile"
GSC="C:/Gambit-C/4.0b20/bin/gsc"
all: main.exe mydll.dll main
main.exe: main.c mydll.dll mydll.h gcc -Wall -o main.exe main.c mydll.dll
mydll.dll: mydll.c mydll_.c gcc -shared -IC:/Gambit-C/4.0b20/include -LC:/Gambit-C/ 4.0b20/lib -o mydll.dll mydll.c mydll_.c -lgambc -lwsock32 -lws2_32
mydll.c: mydll.scm $(GSC) -c mydll.scm
mydll_.c: mydll.c $(GSC) -link mydll.c ********************************************************************** /* File: "main.c" */
#include <stdio.h>
#include "mydll.h"
int main () { printf ("func1 (10, "*") = %d\n", func1 (10, "*")); printf ("func2 ("hello") = %s\n", func2 ("hello")); return 0; } ********************************************************************** /* File: "mydll.h" */
int func1 (int n, char* s); char* func2 (char* s); ********************************************************************** ;; File: "mydll.scm"
;;;----------------------------------------------------
;; Initialize Gambit-C runtime system when "mydll.dll" ;; is loaded.
(c-declare #<<c-declare-end
#define LINKER ____20_mydll__
___BEGIN_C_LINKAGE extern ___mod_or_lnk LINKER (___global_state_struct*); ___END_C_LINKAGE
___setup_params_struct setup_params;
BOOL WINAPI DllMain (HINSTANCE hinst, DWORD reason, LPVOID ptr) { switch (reason) { case DLL_PROCESS_ATTACH: ___setup_params_reset (&setup_params); setup_params.version = ___VERSION; setup_params.linker = LINKER; #if 1 setup_params.debug_settings = (___DEBUG_SETTINGS_REPL_STDIO << ___DEBUG_SETTINGS_REPL_SHIFT); #endif return ___setup (&setup_params) == ___FIX(___NO_ERR);
case DLL_PROCESS_DETACH: ___cleanup (); break; }
return FALSE; }
c-declare-end )
;;;----------------------------------------------------
;; Procedures exported by "mydll.dll":
(c-define (func1 n s) (int char-string) int "func1" "" (let loop ((i 0)) (if (< i n) (begin (display s) (loop (+ i 1))))) (expt 2 n))
(c-define (func2 s) (char-string) char-string "func2" "" (list->string (reverse (string->list s))))
;;;----------------------------------------------------
(display "hello from mydll.scm\n") **********************************************************************