6

かなり大きなC++プロジェクトがあり、現在VS2010に移行し、途中でいくつかのライブラリを更新しています。これまでのところ、すべてが正常に構築されていますが、(私にとっては)非常に奇妙なエラーが発生し、明らかにいくつかの(編集:非)標準のC関数とシンボルが定義されていません。

error C2039: 'strdup' : is not a member of '`global namespace''    ...\ACE_wrappers\ace\OS_NS_string.inl    222
...
error C2065: 'O_WRONLY' : undeclared identifier                    ...\ACE_wrappers\ace\OS_NS_unistd.inl    1057
...

これは、次の関数と記号に影響します。

strdup      getcwd      O_WRONLY
putenv      swab        O_TRUNC
access      unlink      S_IFDIR
chdir       mkdir       S_IFREG
rmdir       tempnam     O_RDONLY
isascii

私が実験したACEのインクルードファイルの一部は、strdup次のような部分でした。

ACE_INLINE char *
ACE_OS::strdup (const char *s)
{
#  if (defined (ACE_LACKS_STRDUP) && !defined(ACE_STRDUP_EQUIVALENT)) \
  || defined (ACE_HAS_STRDUP_EMULATION)
  return ACE_OS::strdup_emulation (s);
#  elif defined (ACE_STRDUP_EQUIVALENT)
  return ACE_STRDUP_EQUIVALENT (s);
#  elif defined (ACE_HAS_NONCONST_STRDUP)
  return ::strdup (const_cast<char *> (s));
#else
  return ::strdup (s);
#  endif /* (ACE_LACKS_STRDUP && !ACE_STRDUP_EQUIVALENT) || ... */
}

上と下の他の関数にも同様のセクションがたくさんあり、それらはすべて正常にコンパイルされます。

私の場合のパスは最後のパスreturn ::strdup (s);です。VSでF12を押すと、C標準ライブラリ::strdupの宣言に移動します。string.h

ビルドした名前空間修飾子を削除すると、IntelliSenseは再帰呼び出しであると言っているので、おそらく機能しません。名前空間を変更すると、他のいくつかのプロジェクトから、さらにstd::約270のエラーが発生します。関数を変更するとビルドされます。非常に最初のものを含めると何も変わりません。::_strdupstring.h

(注意:「ビルドする」とは、「この特定のコンパイラエラーはその場所で消えますが、他の関数に関するエラーは明らかに残ります。)」を指します。

私はここで少し途方に暮れています。多くの大規模なライブラリは、標準ライブラリに対して独自の抽象化を構築するか、デフォルトでは存在しないものを提供することに気付きました。これは、ACEとImageMagickがすでに衝突しているポイントでした(両方ともtypedef互換ssize_t性のない定義で)。かなりの数のライブラリを取得しているので(現時点では正確な概要もわかりません)、これは別の衝突である可能性があります。これは、インクルードの順序が間違っているなどの理由で発生します。これは、ACEからの同じインクルードが同じソリューションの他のプロジェクトで明らかに正常に機能するという事実によっても示唆されています。

誰かが私が少なくともここで何を探すことができるかについての考えを持っていますか?ビルドログはわずか24k行であるため、問題のあるACEヘッダーの前に含まれる/showIncludesことを除いて、多くのパターンは正確には表示されません。string.h

また、ライブラリのソースコードを変更したくないのは、新しいバージョンに更新した場合にのみ、ライブラリのソースコードが再び噛み付くからです。

4

3 に答える 3

4

多くの標準C関数と記号が定義されていません

strdup標準のC関数ではありません。POSIXで定義されていますが、CまたはC++では定義されていません。MSDNの引用:

これらのPOSIX関数は、Visual C ++ 2005以降で非推奨になりました。代わりに、ISO C ++準拠の_strdup、_wcsdup、_mbsdupを使用してください。

あなたがリストしたシンボルはどれも標準のC関数ではないように私には思えます。

于 2012-11-28T14:45:43.010 に答える
1

12MiBのプリプロセッサ出力を見るように促したMarkBのコメントで、私はそれを解決することができました。string.hが定義されているスニペットでは、strdup次のようになります。

#if     !__STDC__

...

_Check_return_ _CRT_NONSTDC_DEPRECATE(_strdup) _CRTIMP char * __cdecl strdup(_In_opt_z_ const char * _Src);

この単一のプロジェクトが__STDC__シンボルを定義しているため、多くの非標準Cであるが、まだC標準ライブラリに残っている(ありがとう、Robφは問題を解決していません)機能が消えてしまいました。完全に。

私はそれらが非推奨であることを知っています、私はそう言うたくさんの警告を受けました。ただし、前述のように、サードパーティライブラリへのプロジェクト固有のパッチは維持していません。更新した場合に同じ楽しみをもう一度楽しむために使用しています。

于 2012-11-28T15:13:38.210 に答える
0

VSを正しく理解していればstrdup、などの関数名は現在非推奨になっています(POSIXに準拠していないと思います)。下線付きのバージョンを使用する必要があります。

これが私に起こったとき、私はグローバル検索と置換を実行しました。それは賢明なことのように思われ、将来のためにソースコードを良好な状態に保つからです(VS 2012はすでにリリースされています!:))。

于 2012-11-28T14:45:23.773 に答える