[gambit-list] Compiling Gambit-C to dll and loading into .NET

Marc Feeley feeley at iro.umontreal.ca
Tue Feb 13 13:09:29 EST 2007


-----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")
**********************************************************************

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (Darwin)

iD8DBQFF0f7Z//V9Zc2T/v4RAviUAJ9JyTlr1/8F/0PSgLjnbYnUu5c0iACgt2vj
xH8nFmoubDDHOCqpwYLTc8c=
=61nA
-----END PGP SIGNATURE-----



More information about the Gambit-list mailing list