ヘッダーファイルでtypedefにてsigned charを定義した場合の回避


toshiba  2010-01-15 18:37:13  No: 71267  IP: [192.*.*.*]

開発をC言語で行い、VC++でパソコンで動作を確認しています。
環境は、icrosoft Visual Studio .NET  Vc7です。

ヘッダーファイルにtypedefでsigned char を  CHAR  と定義しました。
ビルドを行ったとき、WinNT.hに既に定義があるため、
C2371  再定義されています。異なる基本形ですとなり、エラーになりました。
この場合、回避策はないのでしょうか。

よろしくお願い致します。

編集 削除
επιστημη  URL  2010-01-15 18:48:59  No: 71268  IP: [192.*.*.*]

どのように回避したいのかしら。

エラーにならないとすれば、どうなればいいですか?

C++であれば
namespace my { typedef signed char CHAR; }

とでもしておけば、
CHAR x; /* WinNT.hにあるCHAR
my::CHAR y; /* オレが定義したCHAR */
のように使い分けができるんですが...

編集 削除
toshiba  2010-01-15 19:40:26  No: 71269  IP: [192.*.*.*]

質問をさせていただきましたtoshibaです。
言葉足らずで申し訳ありません。
回避は、VC++側で対応したい思いです。
cppファイルはできるだけ改造をしない方向で現在検討をしています。
なにか良い案がありましたらお教えください。

編集 削除
tetrapod  2010-01-15 23:06:19  No: 71270  IP: [192.*.*.*]

いや、だから何がどうなれば解決なの?それがわからなきゃどうにもならん。

VC++ 側で解決とはどういうことを意図してるわけ?
まさか WINNT.h を書き換えようとか考えている?そりゃダメさ。

#include <winnt.h> を、直接的にも間接的にもしないようにするか
自分で CHAR を定義しないようにするか
どっちかしかないだろう。

編集 削除
yoh2  2010-01-15 23:44:03  No: 71271  IP: [192.*.*.*]

toshibaさんが置かれている状況は、以下のどちらかだと思うのですが、
いずれでしょうか? またはその他?

1. C言語で開発した成果物は、それ単体でひとつのプログラム。
   Win32 APIは使っていない。単にビルド環境としてVC++を選んだだけ。
   それなのになぜかインクルードされたWinNT.hの定義とかち合って困っている。

2. C言語で開発した成果物というのはライブラリ。
   このライブラリ自体はWin32 APIを使っていない。
   これをWin32 APIを用いるプログラムに組み込んで使いたいが、
   CHARの定義がWin32 APIとかち合ってうまく組込めない。

1ならプロジェクトの設定で簡単に解決できます。
一方、2だとかなり大変で、C言語で開発したソースをできる限り改変せずに、
となると、可能だとしてもかなり無理矢理な方法になってしまいます。

編集 削除
toshiba  2010-01-16 23:34:36  No: 71272  IP: [192.*.*.*]

ご回答ありがとうございます。
yoh2さん、私の置かれている状況は、2です。
もしよろしければ、1の場合の解決方法である
プロジェクトの設定を教えていただけないでしょうか。
よろしくお願いします。

編集 削除
yoh2  2010-01-17 00:58:41  No: 71273  IP: [192.*.*.*]

1の場合、プロジェクトの種類やプリコンパイルヘッダの設定を誤って、
予期せずにWin32 API関連のヘッダをインクルードしている状況を
想定していましたので、2を解決する役には立ちません。
プロジェクトの種類をコンソールにして、プリコンパイルヘッダを使用しない
設定にする、という解決方法です。

2の場合、Win32 APIを使用する部分では絶対に自前のCHARを使うことはできないので、
それを大前提として考える必要があります。
つまり、ソースを全く変更しない、という選択肢は取れないということです。
自前のCHARを別名に変えるのが一番単純で確実な方法ですけれど、それがダメなら、
他の方と同様、どうなれば解決と言えるの? という疑問が浮かびます。

漠然として答えづらいなら、せめて以下について説明をお願いします。

A. ソースを変更したくない理由。
B. ソースをどの程度なら変更してよいか(回答はAとペアになるかな?)。
C. 他に何か制約はあるか?

編集 削除
toshiba  2010-01-17 23:06:10  No: 71274  IP: [192.*.*.*]

yoh2さん
返信ありがとうございます。
A:Cソースがメインであり、サブであるVC++は優先できない。
    Cソースで開発をしており、あまりいじりたくない。

根本的に、名前変更がベストですね。試行してみます。
VC++の設定やツールでなんとかできないかと模索していました。
ありがとうございます。

編集 削除
yoh2  2010-01-19 00:05:18  No: 71275  IP: [192.*.*.*]

そういうことなら、こういった方法もありかも。
ただし、バッドノウハウに属すると思われるのでできれば避けた方がいいかと。
既に、Windowsプラットホーム以外でそのCソースが広く使われていて、そちらまで
変更するのは手間が大きいが、Windows版と二重管理するのもつらい、といった
場合なら使えるかな?

1. プロジェクトを件のCソース(static library または DLL)とWindows依存部分のふたつに分ける。

2. 件のCソースのヘッダ(全ヘッダに対して)を以下のように変更する。

#if defined(RENAME_CHAR)
#undef CHAR
#define CHAR MY_CHAR
#endif

...(元のヘッダの中身)...

#if defined(RENAME_CHAR)
#undef CHAR
#endif


3. Windows依存部分のプロジェクトの設定で、マクロRENAME_CHARを設定しておく。

4. Windows依存部分のソースではCHARではなくMY_CHARを使う。

※「RENAME_CHAR」、「MY_CHAR」はお好みの名前でどうぞ。

編集 削除