<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=US-ASCII">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2653.12">
<TITLE>Linking to C++ problems</TITLE>
</HEAD>
<BODY>
<P><FONT SIZE=2>Hello,</FONT>
</P>
<P><FONT SIZE=2>I am using Gambit4b12 to write a plugin for a C++ program.</FONT>
<BR><FONT SIZE=2>I've done some tests and had some success although right now I'm having some problems when using it in a DLL.</FONT>
</P>
<P><FONT SIZE=2>First I would like to suggest a small improvement for the C code generation.</FONT>
<BR><FONT SIZE=2>Maybe I'm missing a switch to pass to gsc but every time I generate the C code I have to add extern "C" {} wrapper around each file after I move all the #include outside that block. I also noticed that gambit.c doesn't have a extern "C" wrapper and I had to add it.</FONT></P>
<P><FONT SIZE=2>I think it would be simple to automatically add:</FONT>
<BR><FONT SIZE=2>#ifdef __cplusplus extern "C" {} #endif wrapper when generating the code.</FONT>
<BR><FONT SIZE=2>I don't know how easy would be to extract the includes in c-declare outside that wrapper but it would be nice to avoid manually editing the file.</FONT></P>
<P><FONT SIZE=2>The problem I'm having right now is that the code which runs fine in a single standalone program crashes when is called in a loaded DLL.</FONT></P>
<P><FONT SIZE=2>I think it must be something in the way the initialization has to be done but the documentation is not too clear.</FONT>
</P>
<P><FONT SIZE=2>If someone would be able to give me a hint I would appreciate it.</FONT>
<BR><FONT SIZE=2>I am using mingw on Windows and I get this error:</FONT>
</P>
<P><FONT SIZE=2>Program received signal SIGSEGV, Segmentation fault.</FONT>
<BR><FONT SIZE=2>0x1012a67f in ___CHARSTRING_to_UCS2STRING ()</FONT>
<BR><FONT SIZE=2> from c:\Gambitc_project\finalePlugin\testing\test.dll</FONT>
<BR><FONT SIZE=2>(gdb) bt</FONT>
<BR><FONT SIZE=2>#0 0x1012a67f in ___CHARSTRING_to_UCS2STRING ()</FONT>
<BR><FONT SIZE=2> from c:\Gambitc_project\finalePlugin\testing\test.dll</FONT>
<BR><FONT SIZE=2>#1 0x00000000 in ?? () from</FONT>
<BR><FONT SIZE=2>#2 0x0022fe68 in ?? ()</FONT>
<BR><FONT SIZE=2>#3 0x101248b1 in ___alloc_mem ()</FONT>
<BR><FONT SIZE=2> from c:\Gambitc_project\finalePlugin\testing\test.dll</FONT>
<BR><FONT SIZE=2>Previous frame inner to this frame (corrupt stack?)</FONT>
</P>
<P><FONT SIZE=2>The code is bellow.</FONT>
</P>
<P><FONT SIZE=2>Thank you,</FONT>
<BR><FONT SIZE=2>Dan Hristodorescu.</FONT>
</P>
<BR>
<P><FONT SIZE=2>- Main program:</FONT>
<BR><FONT SIZE=2>#include <windows.h></FONT>
<BR><FONT SIZE=2>#include <stdio.h></FONT>
<BR><FONT SIZE=2>#include "note.h"</FONT>
</P>
<BR>
<P><FONT SIZE=2>typedef void (*EntryPointfuncPtr)(EXNOTE*);</FONT>
<BR><FONT SIZE=2>EntryPointfuncPtr callEntryPoint; </FONT>
<BR><FONT SIZE=2>HINSTANCE library;</FONT>
</P>
<P><FONT SIZE=2>int main(int argc,char **argv)</FONT>
<BR><FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>library = LoadLibrary("test.dll"); </FONT>
<BR> <FONT SIZE=2>// Check to see if the library was loaded successfully </FONT>
<BR> <FONT SIZE=2>if (library == 0)</FONT>
<BR> <FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>printf("Couldn't load the DLL");</FONT>
<BR> <FONT SIZE=2>exit(1);</FONT>
<BR> <FONT SIZE=2>} </FONT>
<BR><FONT SIZE=2> EXNOTE* note1 = new EXNOTE();</FONT>
<BR><FONT SIZE=2> note1->tcd=1;</FONT>
<BR><FONT SIZE=2> note1->alteration=1;</FONT>
<BR><FONT SIZE=2> note1->noteID=1;</FONT>
<BR><FONT SIZE=2> note1->flag=1;</FONT>
<BR><FONT SIZE=2> printf("Address=0x%X\n", note1);</FONT>
<BR><FONT SIZE=2> </FONT>
<BR> <FONT SIZE=2>callEntryPoint = (EntryPointfuncPtr)GetProcAddress(library,"_Z10entryPointP6EXNOTE");</FONT>
<BR> <FONT SIZE=2>(*callEntryPoint)(note1);</FONT>
<BR> <FONT SIZE=2>printf("Note->tcd= %d\n", note1->tcd);</FONT>
<BR><FONT SIZE=2> printf("Note->alteration= %d\n", note1->alteration);</FONT>
<BR><FONT SIZE=2> printf("Note->noteID= %d\n", note1->noteID);</FONT>
<BR><FONT SIZE=2> printf("Note->flag= %d\n", note1->flag);</FONT>
<BR><FONT SIZE=2> delete note1; </FONT>
<BR><FONT SIZE=2>}</FONT>
</P>
<P><FONT SIZE=2>DLL code:</FONT>
<BR><FONT SIZE=2>#include <windows.h></FONT>
<BR><FONT SIZE=2>#include <stdio.h></FONT>
<BR><FONT SIZE=2>#include "note.h"</FONT>
</P>
<P><FONT SIZE=2>extern "C" void pluginEntry(EXNOTE*);</FONT>
</P>
<P><FONT SIZE=2>#define ___VERSION 40062</FONT>
<BR><FONT SIZE=2>#include "gambit.h"</FONT>
</P>
<P><FONT SIZE=2>#define SCHEME_LIBRARY_LINKER ____20_testscm__</FONT>
</P>
<P><FONT SIZE=2>___BEGIN_C_LINKAGE</FONT>
<BR><FONT SIZE=2>extern ___mod_or_lnk SCHEME_LIBRARY_LINKER (___global_state_struct*);</FONT>
<BR><FONT SIZE=2>___END_C_LINKAGE</FONT>
</P>
<P><FONT SIZE=2>CALLBACK void entryPoint(EXNOTE* note1)</FONT>
<BR><FONT SIZE=2>{</FONT>
<BR><FONT SIZE=2> ___setup_params_struct setup_params;</FONT>
<BR><FONT SIZE=2> ___setup_params_reset (&setup_params);</FONT>
<BR><FONT SIZE=2> setup_params.version = ___VERSION;</FONT>
<BR><FONT SIZE=2> setup_params.linker = SCHEME_LIBRARY_LINKER;</FONT>
<BR><FONT SIZE=2> ___setup (&setup_params); </FONT>
</P>
<P><FONT SIZE=2> pluginEntry(note1);</FONT>
</P>
<P><FONT SIZE=2> ___cleanup ();</FONT>
<BR><FONT SIZE=2>}</FONT>
</P>
<P><FONT SIZE=2>note.h file:</FONT>
<BR><FONT SIZE=2>#ifndef _NOTE_H_</FONT>
<BR><FONT SIZE=2>#define _NOTE_H_</FONT>
</P>
<P><FONT SIZE=2>typedef short twobyte; </FONT>
<BR><FONT SIZE=2>typedef unsigned long ufourbyte; </FONT>
<BR><FONT SIZE=2>typedef ufourbyte FLAG_32;</FONT>
</P>
<P><FONT SIZE=2>class EXNOTE</FONT>
<BR><FONT SIZE=2>{</FONT>
<BR><FONT SIZE=2>public:</FONT>
<BR> <FONT SIZE=2>twobyte tcd;</FONT>
<BR> <FONT SIZE=2>twobyte alteration;</FONT>
<BR> <FONT SIZE=2>twobyte noteID;</FONT>
<BR> <FONT SIZE=2>FLAG_32 flag;</FONT>
</P>
<P> <FONT SIZE=2>EXNOTE() : tcd(0), alteration(0), noteID(0), flag(0) {}</FONT>
<BR> <FONT SIZE=2>~EXNOTE() {}</FONT>
<BR><FONT SIZE=2>}; </FONT>
<BR><FONT SIZE=2>#endif</FONT>
</P>
<P><FONT SIZE=2>Scheme code:</FONT>
</P>
<P><FONT SIZE=2>(c-declare "</FONT>
<BR><FONT SIZE=2>#include \"note.h\"</FONT>
<BR><FONT SIZE=2>")</FONT>
</P>
<P><FONT SIZE=2>(c-define-type twobyte short)</FONT>
<BR><FONT SIZE=2>(c-define-type ufourbyte unsigned-long)</FONT>
<BR><FONT SIZE=2>(c-define-type FLAG_32 ufourbyte)</FONT>
</P>
<P><FONT SIZE=2>;;</FONT>
<BR><FONT SIZE=2>;;;; EXNOTE</FONT>
<BR><FONT SIZE=2>;;;</FONT>
</P>
<P><FONT SIZE=2>(c-define-type EXNOTE* (pointer "EXNOTE"))</FONT>
</P>
<P><FONT SIZE=2>(define EXNOTE-tcd </FONT>
<BR><FONT SIZE=2> (c-lambda (EXNOTE*)</FONT>
<BR><FONT SIZE=2> twobyte</FONT>
<BR><FONT SIZE=2> "___result = ___arg1->tcd;"))</FONT>
</P>
<P><FONT SIZE=2>(define EXNOTE-tcd-set!</FONT>
<BR><FONT SIZE=2> (c-lambda (EXNOTE* twobyte)</FONT>
<BR><FONT SIZE=2> void</FONT>
<BR><FONT SIZE=2> "___arg1->tcd = ___arg2;"))</FONT>
</P>
<P><FONT SIZE=2>(define transpose-note </FONT>
<BR><FONT SIZE=2> (lambda (note step)</FONT>
<BR><FONT SIZE=2> (EXNOTE-tcd-set! note (+ (EXNOTE-tcd note) step))))</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2>(c-define (pluginEntry x) (EXNOTE*) void "pluginEntry" "extern" </FONT>
<BR><FONT SIZE=2> (write x)</FONT>
<BR><FONT SIZE=2> (newline)</FONT>
<BR><FONT SIZE=2> (transpose-note x 3))</FONT>
</P>
<BR>
</BODY>
</HTML>