tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Odd problem when using variables defined in header fi


From: Webmaster Hales
Subject: Re: [Tinycc-devel] Odd problem when using variables defined in header files for a .dll
Date: Thu, 16 Mar 2017 10:43:47 +1100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0 SeaMonkey/2.46

Thankyou for your help Grischka and Steven, I now have things working.


I've had a fiddle with the three magic keywords that I've seen so far:

  • extern
  • __declspec(dllexport)
  • __declspec(dllimport)


In practice it seems that only the first two are necessary or work properly.

Attached is a fixed version of my earlier small example (tccdll_exampleB).  Here are the definitions I use in it:

main.c:
extern int Fred;
extern void SetFred(int newvalue);
extern int GetFred();

thedll.c:
__declspec(dllexport) int Fred;
__declspec(dllexport) void SetFred(int newvalue) 
__declspec(dllexport) int GetFred()

Using dllimport in main.c seems to do absolutely nothing.  'extern' is what fixes the problem on this end.

Using extern in the thedll.c seems to do absolutely nothing (other than make the compiler unhappy if you apply it to int Fred).  dllexport is what fixes the problem on this end. 

Is this how things are supposed to behave?


You can even run the entire pdcurses + demo directly from source code
(which in fact doesn't require any changes to pdcurses or TCC):

    tcc -I. pdcurses/*.c win32/*.c -ladvapi32 -luser32 -run demos/firework.c

Beautiful, thankyou.  

I thought I encountered header-file errors when I tried this, I'll have to see how things go again.  I was probably using the old/stable version of TCC.


Alternatively you could patch TCC to treat dllimport as extern
automatically (as do mingw or msvc). In tccgen.c:

    @@ -7022,9 +7022,9 @@ static int decl0(int l, int is_for_loop_init)
                 if (ad.a.weak)
                     type.t |= VT_WEAK;
     #ifdef TCC_TARGET_PE
                 if (ad.a.func_import)
    -                type.t |= VT_IMPORT;
    +                type.t |= VT_IMPORT, btype.t |= VT_EXTERN;
                 if (ad.a.func_export)
                     type.t |= VT_EXPORT;
     #endif
                 type.t |= ad.a.visibility << VT_VIS_SHIFT;

(If you want this to be part of the upcoming tcc 0.9.27 release,
feel free to apply such patch to our 'mob' branch).

Is there any sort of situation where this would cause issues?  Given that the dllimport keyword does not actually seem to do anything at the moment, I'm not sure.

Otherwise: I'll have a go at registering and patching.

Regards, Hales




grischka wrote:
William Hales wrote:
Thankyou, but this does not seem to work.  I just tried adding:

    __declspec(dllimport) extern WINDOW *stdscr;

...to the start of my main.c, and it did not change the resulting program behaviour.  (No warnings or errors either, and I'm using -Wall).

[Screenshot. Let's see if the mailing list supports this.]

Sure that doesn't work, no surprise ;)

Because in C, additional extern declarations for the same symbol (with
the same type) are allowed but do not override any non-extern definitions
before or after.

Therefor you need to change the already existing declaration, that
is in curses.h, just add the single word 'extern' in the right place:

    @@ -395,9 +395,9 @@ typedef struct
     #ifdef PDC_DLL_BUILD
     # ifdef CURSES_LIBRARY
     #  define PDCEX __declspec(dllexport) extern
     # else
    -#  define PDCEX __declspec(dllimport)
    +#  define PDCEX __declspec(dllimport) extern
     # endif
     #else
     # define PDCEX extern
     #endif

     PDCEX  int          LINES;        /* terminal height */
     PDCEX  int          COLS;         /* terminal width */
     PDCEX  WINDOW       *stdscr;      /* the default screen window */

Alternatively you could patch TCC to treat dllimport as extern
automatically (as do mingw or msvc). In tccgen.c:

    @@ -7022,9 +7022,9 @@ static int decl0(int l, int is_for_loop_init)
                 if (ad.a.weak)
                     type.t |= VT_WEAK;
     #ifdef TCC_TARGET_PE
                 if (ad.a.func_import)
    -                type.t |= VT_IMPORT;
    +                type.t |= VT_IMPORT, btype.t |= VT_EXTERN;
                 if (ad.a.func_export)
                     type.t |= VT_EXPORT;
     #endif
                 type.t |= ad.a.visibility << VT_VIS_SHIFT;

(If you want this to be part of the upcoming tcc 0.9.27 release,
feel free to apply such patch to our 'mob' branch).

Which you prefer.

Here is a batch file snippet to build pdcurses and demo with TCC:

    tcc -I. -DPDC_DLL_BUILD -o pdcurses.dll -shared -rdynamic ^
       pdcurses/*.c win32/*.c -include stdlib.h -ladvapi32

    tcc -I. -DPDC_DLL_BUILD -lpdcurses -L. demos/firework.c

    .\firework
    pause

You can also run the demo directly from source code, like this:

    tcc -I. -DPDC_DLL_BUILD -lpdcurses -L. -run demos/firework.c

You can even run the entire pdcurses + demo directly from source code
(which in fact doesn't require any changes to pdcurses or TCC):

    tcc -I. pdcurses/*.c win32/*.c -ladvapi32 -luser32 -run demos/firework.c


(pdcurses from: https://github.com/Bill-Gray/PDCurses/archive/master.zip)

--- grischka


Regards, Hales

William Hales wrote:
Hello,

I have been having a problem with tcc when linking my project against a dll.  The dll and my project share variables through a header file.  This works fine with gcc, but when compiled with tcc my program and the dll end up with completely unique copies of the variables in the .h file, rather than sharing them.

tcc requires 'extern' on the application (program) side, for example

    __declspec(dllimport) extern int foo;

-- gr




_______________________________________________
Tinycc-devel mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Attachment: tccdll_exampleD.zip
Description: Zip archive


reply via email to

[Prev in Thread] Current Thread [Next in Thread]