myriachan | 1 Mar 22:08 2008
Picon
Picon

Incorrect vtable generation in MinGW?

I noticed that MinGW's G++ doesn't make vtables using the same algorithm as Visual C++, which can break COM
interfaces.  If there are two overloaded functions with the same name, Visual Studio will group the
functions of the same name together instead of preserve the ordering specified in the virtual table.

Input program:

struct Vtable
{
  virtual void Overloaded(int) = 0;
  virtual void Other() = 0;
  virtual void Overloaded(Vtable&) = 0;
};

void Function(Vtable& param)
{
  param.Overloaded(param);
}

Visual Studio assembly code (/Ox /Oy-):

	push	ebp
	mov	ebp, esp
	mov	ecx, DWORD PTR 8[ebp]
	mov	eax, DWORD PTR [ecx]
	mov	edx, DWORD PTR [eax]
	push	ecx
	call	edx
	pop	ebp
	ret

(Continue reading)

Ken MacKay | 1 Mar 23:48 2008
Picon

Removing dependency on mingwm10.dll by manually running __mingwthr_run_key_dtors()

So I have a C++ program with threads that throws exceptions, and I  
would like to remove the dependency on mingwm10.dll. My plan was to  
manually run __mingwthr_run_key_dtors() on thread exit; basically my  
thread entry function would look like this:

DWORD WINAPI threadFunction(LPVOID obj)
{
   try
   {
     // ... run the thread ...
   }
   catch(...)
   { // catch all exceptions
   }

   __mingwthr_run_key_dtors();
}

The idea would be that I wouldn't call ExitThread() or any of it's  
friends, so the thread would always call __mingwthr_run_key_dtors()  
before terminating.

It seems like this should work, but I have having some issues. Here  
is what I did so far:

First, I modified ___mingwthr_add_key_dtor() (in mthr.c) so that it  
adds to the list of destructors using  
InterlockedCompareExchangePointer() rather than using a  
CRITICAL_SECTION (to avoid having to initialize the critical  
section). I didn't bother changing ___mingwthr_remove_key_dtor()  
(Continue reading)

Ross Ridge | 2 Mar 00:29 2008
Picon
Picon

Re: Incorrect vtable generation in MinGW?

myriachan writes:
>The real question is, which compiler is incorrect here according to COM?

Neither, it's your code that's incorrect.  Overloading methods isn't
supported by COM.  The MIDL compiler won't let you define an interface
with two methods that have same name.  It also won't let you define a
method that takes reference type as one of it's arguments.  You should
only use C types in your interface, otherwise you'll probably run into
other incompatibilites between Visual C++ and MinGW.

					Ross Ridge

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
MinGW-users mailing list
MinGW-users@...

You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users

Vincent Torri | 2 Mar 21:17 2008
Picon

error with a function declared with dllimport, and used in a struct


Hey,

I have defines a struct like that:

typedef struct
{
   void (*fct) (void);
} Toto;

declared the function my_fct() like that:

__declspec(dllimport) void my_fct (void);

and used it like that:

static const Toto toto = { my_fct };

Then gcc (3.4.5) returns the following error message:

evas_image_main.c:43: error: initializer element is not constant
evas_image_main.c:43: error: (near initialization for `toto.fct')

I don't know very well what dllimport does, so i have no idea of what the 
problem can be. If I remove __declspec(dllimport), it works, of course.

Does someone see the problem (and its solution) ?

thank you

(Continue reading)

Brian Dessent | 2 Mar 21:43 2008
Picon

Re: error with a function declared with dllimport, and used in a struct

Vincent Torri wrote:

> Then gcc (3.4.5) returns the following error message:
> 
> evas_image_main.c:43: error: initializer element is not constant
> evas_image_main.c:43: error: (near initialization for `toto.fct')
> 
> I don't know very well what dllimport does, so i have no idea of what the
> problem can be. If I remove __declspec(dllimport), it works, of course.
> 
> Does someone see the problem (and its solution) ?

The error message is telling you what the problem is.  The address of
my_fct is not a constant that is known at compile time, so you can't
initialize a static variable with it.  When you mark a function as
dllimport, it means that the function resides in another external
module, the address of which is not known until runtime.

Brian

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
MinGW-users mailing list
MinGW-users@...

You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
(Continue reading)

Vincent Torri | 2 Mar 21:57 2008
Picon

Re: error with a function declared with dllimport, and used in a struct


On Sun, 2 Mar 2008, Brian Dessent wrote:

> Vincent Torri wrote:
>
>> Then gcc (3.4.5) returns the following error message:
>>
>> evas_image_main.c:43: error: initializer element is not constant
>> evas_image_main.c:43: error: (near initialization for `toto.fct')
>>
>> I don't know very well what dllimport does, so i have no idea of what the
>> problem can be. If I remove __declspec(dllimport), it works, of course.
>>
>> Does someone see the problem (and its solution) ?
>
> The error message is telling you what the problem is.  The address of
> my_fct is not a constant that is known at compile time, so you can't
> initialize a static variable with it.  When you mark a function as
> dllimport, it means that the function resides in another external
> module, the address of which is not known until runtime.

I've just tried by removing the static const. I have the same error.

any idea ?

Vincent Torri

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
(Continue reading)

Brian Dessent | 2 Mar 22:13 2008
Picon

Re: error with a function declared with dllimport, and used in a struct

Vincent Torri wrote:

> I've just tried by removing the static const. I have the same error.

That doesn't change the situation.  Initializers for global variables
have to be constant and known at link time.  The address of my_fcn is
neither.  You can assign to the variable the value of the function's
address somewhere during program flow (i.e. at runtime), but you cannot
initialize it because that requires knowing the value at link time.

You can also remove the dllimport attribute, and use the fact that the
linker will automatically create a thunk for the function during
linking.  The thunk is just a regular function in the .text section of
the executable, so its address is constant and known at link time.  But
there is an extra level of indirection, a minor performance hit;
essentially doing this is exactly equivalent to:

__declspec(dllimport) void my_fct (void);
void my_fct_helper(void) { my_fct() };
static const Toto toto = { my_fct_helper };

...except that the linker creates the thunk automatically for you.

Brian

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
(Continue reading)

ATS | 1 Mar 23:10 2008
Picon

Re: Incorrect vtable generation in MinGW?

> I noticed that MinGW's G++ doesn't make vtables using the same algorithm as 
> Visual C++, which can break COM interfaces.  If there are two overloaded 
> functions with the same name, Visual Studio will group the functions of 
> the same name together instead of preserve the ordering specified in the 
> virtual table.

Both Visual C++ and G++ puts functions in order of declaration into the 
VTable. However, if the same name is used for several virtual functions,
there is a difference:

- G++ keeps to the order of declaration
- Visual C++ stores functions into the VTable in reversed order of 
declaration. 

Apparently the reason for VC++ to do this is backwards compatability 
with some pre-windows X86 std. COM had to support that. No better reason
than that. 

Stay away from virtual functions with the same name if you want cross
compiler operation. 

Regards
// ATS.

> 
> Input program:
> 
> struct Vtable
> {
>   virtual void Overloaded(int) = 0;
(Continue reading)

Danny Smith | 3 Mar 01:32 2008
Picon

Re: error with a function declared with dllimport, and used in a struct


> -----Original Message-----
> From: mingw-users-bounces@... 
> [mailto:mingw-users-bounces@...] On Behalf 
> Of Vincent Torri
> Sent: Monday, 3 March 2008 9:18 a.m.
> To: mingw-users@...
> Subject: [Mingw-users] error with a function declared with 
> dllimport,and used in a struct
> 
> 
> 
> Hey,
> 
> I have defines a struct like that:
> 
> typedef struct
> {
>    void (*fct) (void);
> } Toto;
> 
> declared the function my_fct() like that:
> 
> __declspec(dllimport) void my_fct (void);
> 
> and used it like that:
> 
> static const Toto toto = { my_fct };
> 
> 
(Continue reading)

zelta | 3 Mar 05:39 2008

x86-mingw32-build.sh-0.0-20061107 bug?

using debian stable, and tried to run the script via:
sh ./x86-mingw32-build.sh i586-pc-mingw32
Everything default, tried just 'c' install and also tried the 
option of adding c++.

Both result in this:

mkdir -p -- ./etc
Configuring in ./etc
configure: creating cache ./config.cache
checking for a BSD-compatible install... /usr/bin/install -c
updating cache ./config.cache
configure: creating ./config.status
config.status: creating Makefile
make[2]: Entering directory `/home/crazy/tmp/mingw-3.4.5/binutils-
2.17.50-20060716-1-src/build/etc'
for f in standards.info configure.info; do \
	  if test -f ../../etc/`echo $f | sed -e 's/.info$/.texi/'`; then \
	    if make "MAKEINFO=/home/crazy/tmp/mingw-3.4.5/binutils-2.17.50-
20060716-1-src/missing makeinfo --split-size=5000000 --split-
size=5000000" $f; then \
	      true; \
	    else \
	      exit 1; \
	    fi; \
	  fi; \
	done
make[3]: Entering directory `/home/crazy/tmp/mingw-3.4.5/binutils-
2.17.50-20060716-1-src/build/etc'
/home/crazy/tmp/mingw-3.4.5/binutils-2.17.50-20060716-1-src/missing 
(Continue reading)


Gmane