Fog Creek Software
Discussion Board




errno and MSVC

Joel's place may not be the best place to post this, but I
can't think of any better. I need help related to MS VC.

I need to use a library that has to be compiled with
MSVC and then link it to my CodeWarrior project.
(I have the source of the library, but it's huge and is a mess
of typedefs and #ifdefs).

Library compiles fine with MSVC.
My projects compiles fine with CW.

But the linker reports three link errors. Maybe I solved them,
but I don't like the way I did it.

1. _errno not defined:

Header file errno.h that came with CodeWarrior
has errno defined like this:

#define errno  (_GetThreadLocalData()->errno)

On the other hand, in header files of MSVC, errno is just
extern int if I am reading/preprocessing file errno.h OK.

#if defined(_DLL)
#define errno (*_errno())
#else
extern int errno;
#endif

To solve my problem I changed both cases in msvc-errno.h
to use _errno() function and then I defined such function in
my CW project:

#include <errno.h>

_cdecl int *_errno(void)
{
  return (&errno);
}

Now it compiles and links fine.


2. __ftol link error:

I had no idea what it does, but then I found this code on
the internet:

void _ftol()
{
    int r;
    _asm
    {
        fistp r
        mov eax, r
    }
}

(http://www.flipcode.com/cgi-bin/msg.cgi?showThread=00004002&forum=general&id=5)

This code compiles and the linker is quiet now. The problem
is, I don't know asm, so I can just guess that I did
something useful.

3. __iob link error

iob just screams IO Buffer.  I found this somewhere and
maybe VC uses _iob for similar stuff:

#define     stdin  (__iob[0])
#define     stdout  (__iob[1])
#define     stderr  (__iob[2])

If I delete all printfs from the library (and replace them with
i/o more appropriate for Windows (MessageBox, etc), would
that solve my problem? But, the library here is using FILE
structures, so maybe I just can't solve this.

I still haven't started with this third step. Somehow I feel
that I should ask someone to tell me what the hell am I
doing? Anyone with deeper knowledge with these pieces of
VC?

Should I forget about all this and try to compile this library
with CodeWarrior? As it is now, CW compiler gives so many
errors (already defined stuff, not defined stuff, nonexisting
headers etc.) It could take even longer before I change it to
compile with CW. What would you people do?

VPC
Thursday, September 02, 2004

There are more things in heaven and Earth, VPC,  Than are dreamt of in your visual C

-Bill Gatespeare

devinmoore.com
Thursday, September 02, 2004

The bad news -- this sort of thing happens whenever you try to apply C or C++ across multiple platforms.  Library inconsistencies, .H file inconsistencies, etc.

The good news -- once you nail down what the inconsistencies are, and what the macro fix is for each, then you should be good to go.

I tend to put this stuff in a 'globals.h' file, then #include globals.h everywhere.  Then, at the top of globals.h, I will put a #define for each platform I want to support.  I know there are default #defines for platforms, but I want more control than using the defaults.

Then, I'll put the #ifdef <platform> lines as wrappers around any customizations needed.

ftol -- I would think that's a 'float to long' conversion.  It's not standard C library stuff.

AllanL5
Thursday, September 02, 2004

As an alternative you might consider would be to compile the MSVC library into a DLL using MSVC, exporting the API you need in your CW app.

Then include a header file to import the API in your CW app.

Joe
Thursday, September 02, 2004

Having been down this road, I agree with the suggestion to use a DLL, exposing either plain C or COM. That's the only sane thing to do, unfortunately. Linking to libs, or trying to expose C++, is going to give you nothing but grief.

Oh, and don't forget about the allocator issues. Memory allocated in one place has to be freed there, since the two things aren't sharing allocators.

Brad Wilson (dotnetguy.techieswithcats.com)
Thursday, September 02, 2004

> As an alternative you might consider would be to compile the MSVC library into a DLL using MSVC, exporting the API you need in your CW app.

It's big - some 30 c files plus 20 h files. And it comes
with make file!!!  I haven't used make files for 10 years
or so. I'll try to convert it into a MSVC project first and then
into dll.

VPC
Thursday, September 02, 2004

> Having been down this road, I agree with the suggestion to use a DLL, exposing either plain C or COM.

Perhaps even that isn't always possible.

For example, I had some code that was built using GCC to use the cygwin library: so I built it as a DLL, so that I could call it from an MSVC EXE.

msvcexe.exe <-> code.dll <->cygwin1.dll

The problem was that the Cygwin run-time library wasn't initialized correctly, unless the application was built using the Gnu compiler rather than MSVC (because, you know, the application has compiler-generated pre-main startup code that helps to initialize the run-time library).

The only fix I was able to make was to build the code using MSVC instead.

Christopher Wells
Thursday, September 02, 2004

> Oh, and don't forget about the allocator issues. Memory allocated in one place has to be freed there, since the two things aren't sharing allocators.

Yes, that too.

Over last few hours, I am more and more inclined to
start converting this thing into a CodeWarrior project.

It can't be that hard! It's mostly standard ANSI C except
5 or 6 sources with native Win32 code. Shuld be possible.

VPC
Thursday, September 02, 2004

> The problem was that the Cygwin run-time library wasn't initialized correctly, unless the application was built using the Gnu compiler

I don't know cygwin, but an MSVC project built into a DLL doesn't have this problem.  In this situation I'd link with the static C runtime library to avoid any dependencies on MSVC runtime library DLLs.

> Over last few hours, I am more and more inclined to
start converting this thing into a CodeWarrior project.

It's an option worth considering of course.  But if the number of functions you need to call is reasonably small, and you have access to some MSVC skills, it would be very easy to go the DLL route.

> Having been down this road, I agree with the suggestion to use a DLL, exposing either plain C or COM

Plain C is what I was thinking of.  If you want to go the COM route and don't trust the C code, you could create a DLL exposing plain C, then a wrapper (in the language of your choice) which exposes COM.

Joe
Thursday, September 02, 2004

> and you have access to some MSVC skills...

Heh!

What I have is MSVC Introductory Edition that comes
with Win32 books and I put it on my computer just two
days ago.

I hopped that maybe some of you guys have the real
thing that maybe comes with full source code of the std
C libraries. At least on Mac version of CodeWarrior I
changed and recompiled the libraries few times over last
10 years.

VPC
Thursday, September 02, 2004

> I found this somewhere and maybe VC uses _iob for similar stuff

Yes it does.

Christopher Wells
Thursday, September 02, 2004

>>... maybe VC uses _iob for similar stuff

> Yes it does.

Thanks Christopher,

I was afraid of that. The library is using FILE structures
and fopen () so this looks as if I'm toast. I could incorporate
Microsoft's library that holds this things into first library
but this could open other issues and more unresolved
externals...

Anyway, sometimes this childish hacking can bring you
somewhere.

VPC
Thursday, September 02, 2004

I suggest porting it to CodeWarrior, or porting your program to VC++. This kind of thing is tiresome, and can be time-consuming, but it's pretty straightforward.

Tom_
Thursday, September 02, 2004

this is just the sort of thing DLLs can deal with. and COM at a higher level.

of course, that's assuming the library doesn't actually export things like file handles as the return value from a function.

mb
Thursday, September 02, 2004

*  Recent Topics

*  Fog Creek Home