Sorry to replay to my own message but I figure out what was the problem. It was just the mangling of DLL exported symbols (I was referring a wrong name); it works fine now.
The only relevant part of the message that remains is the one about the extern "C" generation.
Thanks, Dan.
-----Original Message----- From: Dan Hristodorescu [mailto:dhristodorescu@borderfree.com] Sent: Monday, February 21, 2005 11:31 AM To: gambit-list@IRO.UMontreal.CA Subject: [gambit-list] Linking to C++ problems
Hello, I am using Gambit4b12 to write a plugin for a C++ program. I've done some tests and had some success although right now I'm having some problems when using it in a DLL. First I would like to suggest a small improvement for the C code generation.
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. I think it would be simple to automatically add: #ifdef __cplusplus extern "C" {} #endif wrapper when generating the code. 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. 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. I think it must be something in the way the initialization has to be done but the documentation is not too clear. If someone would be able to give me a hint I would appreciate it. I am using mingw on Windows and I get this error: Program received signal SIGSEGV, Segmentation fault. 0x1012a67f in ___CHARSTRING_to_UCS2STRING () from c:\Gambitc_project\finalePlugin\testing\test.dll (gdb) bt #0 0x1012a67f in ___CHARSTRING_to_UCS2STRING () from c:\Gambitc_project\finalePlugin\testing\test.dll #1 0x00000000 in ?? () from #2 0x0022fe68 in ?? () #3 0x101248b1 in ___alloc_mem () from c:\Gambitc_project\finalePlugin\testing\test.dll Previous frame inner to this frame (corrupt stack?) The code is bellow. Thank you, Dan Hristodorescu.
- Main program: #include <windows.h> #include <stdio.h> #include "note.h"
typedef void (*EntryPointfuncPtr)(EXNOTE*); EntryPointfuncPtr callEntryPoint; HINSTANCE library; int main(int argc,char **argv) { library = LoadLibrary("test.dll"); // Check to see if the library was loaded successfully if (library == 0) { printf("Couldn't load the DLL"); exit(1); } EXNOTE* note1 = new EXNOTE(); note1->tcd=1; note1->alteration=1; note1->noteID=1; note1->flag=1; printf("Address=0x%X\n", note1); callEntryPoint = (EntryPointfuncPtr)GetProcAddress(library,"_Z10entryPointP6EXNOTE"); (*callEntryPoint)(note1); printf("Note->tcd= %d\n", note1->tcd); printf("Note->alteration= %d\n", note1->alteration); printf("Note->noteID= %d\n", note1->noteID); printf("Note->flag= %d\n", note1->flag); delete note1; } DLL code: #include <windows.h> #include <stdio.h> #include "note.h" extern "C" void pluginEntry(EXNOTE*); #define ___VERSION 40062 #include "gambit.h" #define SCHEME_LIBRARY_LINKER ____20_testscm__ ___BEGIN_C_LINKAGE extern ___mod_or_lnk SCHEME_LIBRARY_LINKER (___global_state_struct*); ___END_C_LINKAGE CALLBACK void entryPoint(EXNOTE* note1) { ___setup_params_struct setup_params; ___setup_params_reset (&setup_params); setup_params.version = ___VERSION; setup_params.linker = SCHEME_LIBRARY_LINKER; ___setup (&setup_params); pluginEntry(note1); ___cleanup (); } note.h file: #ifndef _NOTE_H_ #define _NOTE_H_ typedef short twobyte; typedef unsigned long ufourbyte; typedef ufourbyte FLAG_32; class EXNOTE { public: twobyte tcd; twobyte alteration; twobyte noteID; FLAG_32 flag; EXNOTE() : tcd(0), alteration(0), noteID(0), flag(0) {} ~EXNOTE() {} }; #endif Scheme code: (c-declare " #include "note.h" ") (c-define-type twobyte short) (c-define-type ufourbyte unsigned-long) (c-define-type FLAG_32 ufourbyte) ;; ;;;; EXNOTE ;;; (c-define-type EXNOTE* (pointer "EXNOTE")) (define EXNOTE-tcd (c-lambda (EXNOTE*) twobyte "___result = ___arg1->tcd;")) (define EXNOTE-tcd-set! (c-lambda (EXNOTE* twobyte) void "___arg1->tcd = ___arg2;")) (define transpose-note (lambda (note step) (EXNOTE-tcd-set! note (+ (EXNOTE-tcd note) step)))) (c-define (pluginEntry x) (EXNOTE*) void "pluginEntry" "extern" (write x) (newline) (transpose-note x 3))
Afficher les réponses par date
Sorry to replay to my own message but I figure out what was the = problem. It was just the mangling of DLL exported symbols (I was referring a = wrong name); it works fine now.
Great.
The only relevant part of the message that remains is the one about the extern "C" generation.
I don't understand your point here. You should either compile the whole Gambit runtime system and your program with a C compiler, or with a C++ compiler, and then the names will be mangled appropriately. Are you mixing C and C++ code? (this is a bad idea in general because of the way exceptions are handled....)
Marc