<!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>