Discussion:
Convert GCC under Cygwin Name Mangling to VC++ Name Mangling
Francisco J. Royo Santas
2006-12-13 14:52:40 UTC
Permalink
Hello,
I have compiled a .dll file with GCC under Cygwin and I need to access it from
Visual Studio. The problem is the name mangling, VS tries to find a "VS-style"
name and it is different in the DLL. The name in the dll (for the function
FreeLingAnalyzer::initialize(char * *)) is
"__ZN16FreeLingAnalyzer10initializeEPPc" and VS tries to link to
way to force GCC to create MS-style names?
Shouldn't that work better if you use extern "C" {..} around the declarations?
bye Fabi
It doesn't work, I tried to use extern "C" in the class definition .h and the
procedures un .cc and it does not change the mangled names :( It belongs to a
class that would be needed as it is.

thanks and g'bye
John Love-Jensen
2006-12-13 15:57:07 UTC
Permalink
Hi Francisco,

GCC's C++ is not compatible with MS Dev Studio's C++. They have
incompatible C++ ABIs.

Why would you want the MSDevStudio's Visual C++ name mangling?

Sincerely,
--Eljay
Francisco J. Royo Santas
2006-12-13 16:19:32 UTC
Permalink
Post by John Love-Jensen
Hi Francisco,
GCC's C++ is not compatible with MS Dev Studio's C++. They have
incompatible C++ ABIs.
Why would you want the MSDevStudio's Visual C++ name mangling?
Sincerely,
--Eljay
I need it because I have to join a package made for linux with a big windows
project. When I compile it with GCC I do it under Cygwin so it generates an
.exe that, linked to a cygwin dll, runs on Windows platform. I already
built an
.exe version of the package but now I need the DLL to join it to a bigger
project

Thanks and g'bye
John Love-Jensen
2006-12-13 16:34:24 UTC
Permalink
Hi Francisco,

Given your situation, it sounds like the bigger project is using MS Dev
Studio's Visual C++.

The GCC C++ ABI is not compatible with the MS Dev Studio VC++ ABI.

Either the bigger project will need to be compiled with GCC, or your
package-made-for-Linux will have to be compiled with MSVC++, or you will
have to create a C ABI edge that is the interface from the GCC C++ world to
the MSVC++ world.

The C ABI is compatible between the two compilers. The C++ ABIs are not
compatible.

What does "not compatible ABI" mean in this context? The RTTI is
incompatible, the exception handling is incompatible, the name mangling is
incompatible, the parameter pushing is incompatible, the calling convention
is incompatible, the stack clean up is incompatible, the stack unwinding is
incompatible, and probably a handful of other catastrophic differences.

If you write a C edge, you cannot leak RTTI information, or throw an
exception past the C barrier (instant program termination), et cetera.

HTH,
--Eljay
Francisco J. Royo Santas
2006-12-13 18:42:26 UTC
Permalink
Post by John Love-Jensen
Hi Francisco,
Given your situation, it sounds like the bigger project is using MS Dev
Studio's Visual C++.
The GCC C++ ABI is not compatible with the MS Dev Studio VC++ ABI.
Either the bigger project will need to be compiled with GCC, or your
package-made-for-Linux will have to be compiled with MSVC++, or you will
have to create a C ABI edge that is the interface from the GCC C++ world to
the MSVC++ world.
The C ABI is compatible between the two compilers. The C++ ABIs are not
compatible.
What does "not compatible ABI" mean in this context? The RTTI is
incompatible, the exception handling is incompatible, the name mangling is
incompatible, the parameter pushing is incompatible, the calling convention
is incompatible, the stack clean up is incompatible, the stack unwinding is
incompatible, and probably a handful of other catastrophic differences.
If you write a C edge, you cannot leak RTTI information, or throw an
exception past the C barrier (instant program termination), et cetera.
HTH,
--Eljay
Oh :(:( Thank you very much anyway, I hoped it could be possible. How
can I do a
C edge for a C++ class? This class has 6 or 7 variables of types which are
defined inside the DLL so it's a bit complicated because the functions I need
to use in the class make use of these variables which have to be
initialized at
the beginning of the execution and it takes a long time (10 seconds)
while the function takes less than 0.03 seconds. Time is important. If
everything fails,
I will have to create a socket to communicate a gcc-compiled program with the
big VC++-compiled big project but I want to try everything before changing to
this solution.

Thanks and g'bye
Andrew Haley
2006-12-13 18:45:28 UTC
Permalink
Post by Francisco J. Royo Santas
Post by John Love-Jensen
If you write a C edge, you cannot leak RTTI information, or throw an
exception past the C barrier (instant program termination), et cetera.
Oh :(:( Thank you very much anyway, I hoped it could be possible. How
can I do a
C edge for a C++ class?
extern "C", like he said.

Andrew.
Tony Wetmore
2006-12-13 19:47:01 UTC
Permalink
Post by Francisco J. Royo Santas
Oh :(:( Thank you very much anyway, I hoped it could be possible. How
can I do a C edge for a C++ class?
Francisco,

If I understand Eljay correctly, I think he means that you have to write
something like the following:

linuxobject.h
-------------
extern "C" void* createLinuxObject();
extern "C" int callLinuxObjectMethod1( void* linuxObject );
extern "C" int callLinuxObjectMethod2( void* linuxObject );

linuxobject.c
-------------
extern "C" void* createLinuxObject()
{
return (void*) new LinuxObject();
}

extern "C" int callLinuxObjectMethod1( void* linuxObject )
{
return ((LinuxObject*)linuxObject)->method1();
}

extern "C" int callLinuxObjectMethod2( void* linuxObject )
{
try
{
((LinuxObject*)linuxObject)->method2();
}
catch( ... )
{
return LINUX_OBJECT_FAILURE;
}

return LINUX_OBJECT_SUCCESS;
}

As you can see, you have to write C functions for every (externally
callable) method of your class, as well as a function to create an
object and probably one to destroy it as well.

The Visual C++ code would then have to call these C functions, rather
than interacting with your class directly. It is a little messy, but it
should work, since the C ABI *is* standardized across compilers.

But honestly, it sounds like it would be much less complicated to simply
compile your (Linux) code with Visual C++, as Eljay originally suggested.

--
Tony Wetmore
Solipsys Corporation (http://www.solipsys.com)
mailto:***@solipsys.com
John Love-Jensen
2006-12-13 20:25:57 UTC
Permalink
Hi Tony & Francisco,

Excellent example, Tony! That's a good way to describe exactly what I
meant.

I like that you covered catching all exceptions converting them to some form
of error code. And you have to do it for the createLinuxObject, too:

extern "C" void* createLinuxObject()
{
try
{
return (void*) new LinuxObject();
}
catch(...)
{
return NULL;
}
}

And you'll need a release (or dispose or destruct or destory or whatever the
terminology one prefers) function too:

extern "C" int releaseLinuxObject(void* linuxObject)
{
try
{
delete (LinuxObject*)linuxObject;
}
catch(...)
{
// What? Throwing an exception in a destructor? Very bad mojo indeed.
return LINUX_OBJECT_FAILURE;
}

return LINUX_OBJECT_SUCCESS;
}

And quite possibly you may need an initialize and terminate for globals and
other prim-and-proper state for the LinuxObject system as a whole:

extern "C" int initializeLinuxObjectSystem();
extern "C" int terminateLinuxObjectSystem();

I recommend that the initialize / terminate either keep track of a counter
for proper nested initializations; or disallow them completely and fail with
an appropriate error code. Bad mojo to allow multiple initializations and
only one termination.

Sincerely,
--Eljay
Michael Haubenwallner
2006-12-14 08:12:51 UTC
Permalink
Hi Francisco,

as you said you have a shared-library initially built on Linux, I assume
you have some gcc-bound build mechanism (ev. autotools+libtool ?), which
is why you started using gcc on cygwin, right ?

And very likely, you include some system headers not available on
Windows (fex unistd.h) ?

I'm sure it is worth a try to look at 'wgcc', which is a full featured
wrapper around MS 'cl.exe', behaving like gcc as much as possible,
including the ability to build shared libraries, but using MS 'cl.exe'
as the underlying compiler: http://sourceforge.net/projects/interix-wgcc

We are able to build a bunch of opensource packages with cl.exe (through
wgcc) both as static and shared libraries, using their normal build
procedure (mostly automake+autoconf+libtool+GNU make), with minimal
sourcecode changes.
While the build environment is cygwin or interix (eventually MinGW), the
output is real plain windows without the need for any cygwin1.dll or
psxdll.dll.

/haubi/
Post by Francisco J. Royo Santas
Post by John Love-Jensen
Hi Francisco,
Given your situation, it sounds like the bigger project is using MS Dev
Studio's Visual C++.
The GCC C++ ABI is not compatible with the MS Dev Studio VC++ ABI.
Either the bigger project will need to be compiled with GCC, or your
package-made-for-Linux will have to be compiled with MSVC++, or you will
have to create a C ABI edge that is the interface from the GCC C++ world to
the MSVC++ world.
The C ABI is compatible between the two compilers. The C++ ABIs are not
compatible.
What does "not compatible ABI" mean in this context? The RTTI is
incompatible, the exception handling is incompatible, the name mangling is
incompatible, the parameter pushing is incompatible, the calling convention
is incompatible, the stack clean up is incompatible, the stack unwinding is
incompatible, and probably a handful of other catastrophic differences.
If you write a C edge, you cannot leak RTTI information, or throw an
exception past the C barrier (instant program termination), et cetera.
HTH,
--Eljay
Oh :(:( Thank you very much anyway, I hoped it could be possible. How
can I do a
C edge for a C++ class? This class has 6 or 7 variables of types which are
defined inside the DLL so it's a bit complicated because the functions I need
to use in the class make use of these variables which have to be
initialized at
the beginning of the execution and it takes a long time (10 seconds)
while the function takes less than 0.03 seconds. Time is important. If
everything fails,
I will have to create a socket to communicate a gcc-compiled program with the
big VC++-compiled big project but I want to try everything before changing to
this solution.
Thanks and g'bye
--
Michael Haubenwallner SALOMON Automation GmbH
Forschung & Entwicklung A-8114 Friesach bei Graz
mailto:***@salomon.at http://www.salomon.at
No HTML/MIME please, see http://expita.com/nomime.html
Tim Prince
2006-12-18 15:16:49 UTC
Permalink
What I did next was to download 'Microsoft Windows services for Unix'
and tried
to compile and run wgcc there but it was even funnier. After solving
problems
like getting "Memory fault (core dumped)" for every single thing I tried
to do,
I tried to run "./configure" for wgcc and what I got (when compiling
gcc: Internal error: Segmentation fault (program cc1plus)
Please submit a full bug report.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
I have no idea what I can do, can anyone please help me???
Microsoft gives you a broken g++, and advises you to use the gcc support
system? I don't blame you for not following the advice, but you're even
less likely to get help if you don't.
You do want to make sure you don't have different versions of gcc
installed so that they conflict with each other.
Michael Haubenwallner
2006-12-18 15:58:10 UTC
Permalink
On Mon, 2006-12-18 at 16:02 +0100, Francisco J. Royo Santas wrote:
<snip>
I have even turned DEP off.
<snip>
----
As M. Haubenwallner suggested, I tried downloading 'wgcc' but it din't
work for
cygwin as well.
<snip>

wgcc not running on cygwin currently is a known problem, although there
is no known technical issue but just lack of resources.

<snip>
What I did next was to download 'Microsoft Windows services for Unix'
and tried
to compile and run wgcc there but it was even funnier. After solving problems
like getting "Memory fault (core dumped)" for every single thing I
tried to do,
I tried to run "./configure" for wgcc and what I got (when compiling
gcc: Internal error: Segmentation fault (program cc1plus)
Please submit a full bug report.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
As you said above, did you have DEP also disabled when using Interix ?
Interix-shipped gcc requires it to be disabled, at least for SFU 3.5.

And which version of Windows and SFU do you use ?
Windows 2000, XP: SFU 3.5
Windows 2003: SFU 3.5, but does not really work
Windows 2003r2: SUA 5.2 (is a Windows component here)

IMO we should continue wgcc/interix-specific discussion on
interix-wgcc-developer list.

/haubi/
--
Michael Haubenwallner SALOMON Automation GmbH
Forschung & Entwicklung A-8114 Friesach bei Graz
mailto:***@salomon.at http://www.salomon.at
No HTML/MIME please, see http://expita.com/nomime.html
Francisco J. Royo Santas
2006-12-18 15:02:09 UTC
Permalink
Hello once again,

I have tried many things. I will try to explain all of them.

1st:
----
I tried to use the extern "C" and it did link. I created a simple "mydll.dll"
with a "void myproc1() { return; }" and after compiling it with cygwin it
linked under VC++ .net but when I run the program and it has to run
"myproc1" I
get a Windows error-window ".. has encountered a problem and needs to
close. We
are sorry (LoL) for the inconvenience". I have even turned DEP off.

2nd:
----
I tried to do a explicit dll linking. With the same mydll.dll I tried
using the
example provided by VC++ help for explicit linking. The "LoadLibrary" hangs.
When it is at that point the program freezes and does nothing else.

3rd:
----
As M. Haubenwallner suggested, I tried downloading 'wgcc' but it din't
work for
cygwin as well. I read "INSTALL" procedure and it was able to run
"./configure"
and "make" but when I did "make check" I got twice

warning: wrapper header set but not available!
error : execution of task seemed to fail, return code 13568
fatal : compiler queue didn't complete, cannot continue

and at the bottom........

======================
9 of 9 tests failed
(1 tests were not run)
======================
make[2]: *** [check-TESTS] Error 1
make[2]: Leaving directory `/wgcc/build.wgcc/tests'
make[1]: *** [check-am] Error 2
make[1]: Leaving directory `/wgcc/build.wgcc/tests'
make: *** [check-recursive] Error 1

What I did next was to download 'Microsoft Windows services for Unix'
and tried
to compile and run wgcc there but it was even funnier. After solving problems
like getting "Memory fault (core dumped)" for every single thing I
tried to do,
I tried to run "./configure" for wgcc and what I got (when compiling
conftest.cc, a simple main which has a "return 0" statement) was:
gcc: Internal error: Segmentation fault (program cc1plus)
Please submit a full bug report.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

I have no idea what I can do, can anyone please help me???
Post by John Love-Jensen
Hi Francisco,
as you said you have a shared-library initially built on Linux, I assume
you have some gcc-bound build mechanism (ev. autotools+libtool ?), which
is why you started using gcc on cygwin, right ?
And very likely, you include some system headers not available on
Windows (fex unistd.h) ?
I'm sure it is worth a try to look at 'wgcc', which is a full featured
wrapper around MS 'cl.exe', behaving like gcc as much as possible,
including the ability to build shared libraries, but using MS 'cl.exe'
as the underlying compiler: http://sourceforge.net/projects/interix-wgcc
We are able to build a bunch of opensource packages with cl.exe (through
wgcc) both as static and shared libraries, using their normal build
procedure (mostly automake+autoconf+libtool+GNU make), with minimal
sourcecode changes.
While the build environment is cygwin or interix (eventually MinGW), the
output is real plain windows without the need for any cygwin1.dll or
psxdll.dll.
/haubi/
Post by John Love-Jensen
Post by John Love-Jensen
Hi Francisco,
Given your situation, it sounds like the bigger project is using MS Dev
Studio's Visual C++.
The GCC C++ ABI is not compatible with the MS Dev Studio VC++ ABI.
Either the bigger project will need to be compiled with GCC, or your
package-made-for-Linux will have to be compiled with MSVC++, or you will
have to create a C ABI edge that is the interface from the GCC C++
world to
Post by John Love-Jensen
the MSVC++ world.
The C ABI is compatible between the two compilers. The C++ ABIs are not
compatible.
What does "not compatible ABI" mean in this context? The RTTI is
incompatible, the exception handling is incompatible, the name mangling is
incompatible, the parameter pushing is incompatible, the calling
convention
Post by John Love-Jensen
is incompatible, the stack clean up is incompatible, the stack
unwinding is
Post by John Love-Jensen
incompatible, and probably a handful of other catastrophic differences.
If you write a C edge, you cannot leak RTTI information, or throw an
exception past the C barrier (instant program termination), et cetera.
HTH,
--Eljay
Oh :(:( Thank you very much anyway, I hoped it could be possible. How
can I do a
C edge for a C++ class? This class has 6 or 7 variables of types which are
defined inside the DLL so it's a bit complicated because the
functions I need
to use in the class make use of these variables which have to be
initialized at
the beginning of the execution and it takes a long time (10 seconds)
while the function takes less than 0.03 seconds. Time is important. If
everything fails,
I will have to create a socket to communicate a gcc-compiled program with the
big VC++-compiled big project but I want to try everything before changing to
this solution.
Thanks and g'bye
--
Michael Haubenwallner SALOMON Automation GmbH
Forschung & Entwicklung A-8114 Friesach bei Graz
No HTML/MIME please, see http://expita.com/nomime.html
Francisco J. Royo Santas
Christopher Faylor
2006-12-19 02:17:17 UTC
Permalink
Post by Francisco J. Royo Santas
Hello once again,
I have tried many things. I will try to explain all of them.
----
I tried to use the extern "C" and it did link. I created a simple "mydll.dll"
with a "void myproc1() { return; }" and after compiling it with cygwin it
linked under VC++ .net but when I run the program and it has to run
"myproc1" I
get a Windows error-window ".. has encountered a problem and needs to
close. We
are sorry (LoL) for the inconvenience". I have even turned DEP off.
----
I tried to do a explicit dll linking. With the same mydll.dll I tried
using the
example provided by VC++ help for explicit linking. The "LoadLibrary" hangs.
When it is at that point the program freezes and does nothing else.
You can't just link a Cygwin-created DLL into your program without also
going through the type of initialization which is talked about in the
Cygwin FAQ at the Cygwin web site.

OTOH, if you don't need Cygwin's POSIX facilities, you might be able to just
use MinGW's C compiler.

Cygwin: http://cygwin.com/
MinGW: http://mingw.org/

No matter what you do, as you apparently know, you will have to confine
yourself to using C functions rather than C++ since the name mangling
and other conventions are different between gcc and MSVC.

cgf
Francisco J. Royo Santas
2006-12-19 19:53:46 UTC
Permalink
Thanks to C. Faylor and all of you, I finally managed to access the functions
explicitly and works fine, after knowing that cygwin1.dll needs to be
initialized. The problem now is that cygwin blocks the stdout and stderr after
initializing, but it is a problem for cygwin mailing lists, not here

thanks to everyone :)
Post by Christopher Faylor
Post by Francisco J. Royo Santas
Hello once again,
I have tried many things. I will try to explain all of them.
----
I tried to use the extern "C" and it did link. I created a simple "mydll.dll"
with a "void myproc1() { return; }" and after compiling it with cygwin it
linked under VC++ .net but when I run the program and it has to run
"myproc1" I
get a Windows error-window ".. has encountered a problem and needs to
close. We
are sorry (LoL) for the inconvenience". I have even turned DEP off.
----
I tried to do a explicit dll linking. With the same mydll.dll I tried
using the
example provided by VC++ help for explicit linking. The "LoadLibrary" hangs.
When it is at that point the program freezes and does nothing else.
You can't just link a Cygwin-created DLL into your program without also
going through the type of initialization which is talked about in the
Cygwin FAQ at the Cygwin web site.
OTOH, if you don't need Cygwin's POSIX facilities, you might be able to just
use MinGW's C compiler.
Cygwin: http://cygwin.com/
MinGW: http://mingw.org/
No matter what you do, as you apparently know, you will have to confine
yourself to using C functions rather than C++ since the name mangling
and other conventions are different between gcc and MSVC.
cgf
Francisco J. Royo Santas

Loading...