問題タブ [name-decoration]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - C アプリから C++ DLL の変数にアクセスできない
レガシ Visual C++ 6 アプリの修正で行き詰まっています。私が入れたC++ DLLソースで
その結果、(dumpbin /exports blah.dll で示されるように) エクスポート テーブルに MyNewVariable が (きれいに装飾されずに) 表示されます。しかし、C ソース ファイルでアクセスできるように変数を宣言する方法がわかりません。私はさまざまなことを試しました。
しかし、それは私にリンカエラーを与えます:
未解決の外部シンボル "__declspec(dllimport) char * MyNewVariable" (__imp_?MyNewVariable@@3PADA)
トニーが示唆したように(そして私が以前に試したように)、予想される装飾が異なりますが、まだ削除されていません:
未解決の外部シンボル __imp__MyNewVariable
C アプリから C++ DLL 変数にアクセスできるように宣言を作成するにはどうすればよいですか?
答え
botismarius やその他の方々 (皆さんに感謝します) が特定したように、DLL の .lib とリンクする必要がありました。名前が壊れないようにするために、(C ソースで) デコレーターなしで宣言する必要がありました。つまり、.lib ファイルを使用する必要がありました。
c++ - __stdcallでdllをコンパイルするGCC
Visual Studio 2008 内で __stdcall を使用して dll をコンパイルすると、dll 内のコンパイルされた関数名は次のようになります。
関数名
ただし、wx-dev-cpp を使用して GCC を使用して同じ dll をコンパイルすると、GCC は関数が持つパラメーターの数を追加するため、Dependency walker を使用した関数の名前は次のようになります。
FunctionName@numberOfParameters または == FunctionName@8
dll でエクスポートされたシンボルから @nn を削除するように GCC コンパイラに指示するにはどうすればよいですか?
visual-studio-2008 - VC9(MSVC 2008)で許可される装飾名の長さを増やすにはどうすればよいですか?
私はVC8からVC9に移植するためのかなり大きくて複雑なプログラムのセットを持っています。モジュールの1つには、いくつかの階層化されたtypedefがあり、コンパイラーはC4503警告(装飾名は切り捨てられます)を生成します。生成されたLIBファイルは、プロジェクト内の他のモジュールに適切にリンクされません。VC8はこれに問題がなく、装飾プロセスが変更されてさらに長い名前が生成されたか、装飾された名前の長さの内部制限が減少したと結論付けました。これを乗り越えるための最良の方法は何ですか?
レガシーコードの理由から、typedefをstructに置き換えるというMSDNの提案は実用的ではありません。
問題のtypedefは(サニタイズされたコード)です:
visual-c++ - VC8 (VS2005) から VC9 (VS2008) への移植の問題は何ですか?
私は、VC8 (VS2005) でビルドおよびテストされた非常に大規模で複雑なプロジェクト (実際には、119 の「プロジェクト」で構成される「ソリューション」であり、そのほとんどが DLL) を継承しており、それを VC9 に移植するタスクがあります。 (VS2008)。
私が使用した移植プロセスは次のとおりです。
- VC8 .sln ファイルをコピーし、名前を VC9 .sln ファイルに変更します。
- すべての VC8 プロジェクト ファイルをコピーし、名前を VC9 プロジェクト ファイルに変更します。
- すべての VC9 プロジェクト ファイル、s/vc8/vc9 を編集します。
- VC9 .sln、s/vc8/vc9/ を編集します。
- VS2008 で VC9 .sln をロードし、IDE にすべてのプロジェクト ファイルを「変換」させます。
- 適切なビルドが得られるまで、コンパイラとリンカーのエラーを修正します。
これまでのところ、最後のステップで次の問題に遭遇しました。
1) 装飾された名前の計算方法が変更され、名前が切り捨てられました。
これは単なる警告ではありません ( http://msdn.microsoft.com/en-us/library/074af4b6.aspx )。この警告でビルドされたライブラリは、他のモジュールとリンクしません。MSDN に記載されている解決策を適用することは簡単ではありませんが、実行可能でした。この問題については、「VC9 (MSVC 2008) で許可されている修飾名の長さを増やすにはどうすればよいですか?」で個別に対処しました。
2) イテレータにゼロを代入できない変更。これは仕様によるものであり、以前は許可されていたこれらのコーディング エラーを見つけて修正するのはかなり簡単でした。イテレータにゼロを代入する代わりに、値 end() を使用します。
3) for ループのスコープは、ANSI 標準に準拠するようになりました。別の簡単に修正できる問題。
4) プリコンパイル済みヘッダーに必要なスペースが増えます。場合によっては、さらに多くのスペースが必要でした。/Zm999 を使用して最大の PCH スペースを提供することになりました。PCH のメモリ使用量が再び増加した場合は、PCH を完全に使用せずに、ビルド時間の増加に耐える必要があると思います。
5) コピー ctor およびデフォルト dtor の要件の変更。テンプレート クラスでは、特定の条件下で、まだよくわかっていませんが、コンパイラはデフォルトの ctor またはデフォルトの dtor を生成しなくなったようです。これは VC9 のバグだと思いますが、他に何か間違っている可能性があります。もしそうなら、それが何であるかを知りたいです。
6) sln および vcproj ファイルの GUID は変更されませんでした。これは、私が検出できる方法でビルドに影響を与えるようには見えませんが、それでも心配です.
これらすべての問題にもかかわらず、プロジェクトは VC8 でビルド、実行、広範な QA テストに合格したことに注意してください。また、すべての変更を VC8 プロジェクトにバックポートしましたが、以前と同じように (VS2005/VC8 を使用して) ビルドして実行することができます。したがって、VC9 ビルドに必要なすべての変更は、少なくとも下位互換性があるように見えますが、回帰テストはまだ進行中です。
ここで、非常に難しい問題について説明します。VC8 プロジェクトと VC9 プロジェクトの起動シーケンスの違いに遭遇しました。このプログラムは、Andrei Alexandrescu の Book Modern C++ Designで、Loki をモデルにした小さなオブジェクト アロケーターを使用します。このアロケータは、メイン プログラム モジュールで定義されたグローバル変数を使用して初期化されます。
VC8 では、このグローバル変数はプログラム起動の最初に、モジュール crtexe.c のコードから構築されます。VC9 では、最初に実行されるモジュールは crtdll.c で、これは起動シーケンスが変更されたことを示します。起動中の DLL は、グローバル オブジェクトが統計を初期化する前にメモリの割り当てと割り当て解除を行うことで、スモール オブジェクト アロケータを混乱させているように見えます。これにより、誤った診断が行われます。プログラムの動作は実質的に影響を受けていないようですが、QA 担当者は偽の診断がそれらを通り抜けることを許可しません。
DLL をロードする前に、グローバル オブジェクトの構築を強制する方法はありますか?
他にどのような移植の問題が発生する可能性がありますか?
function - DLL 関数パラメーターの検索
文書化されていないDll 関数のパラメーターを見つけるにはどうすればよいですか?
私はインターネット全体を検索し、最終的に 1 つの方法を見つけました。装飾された関数が含まれます。ただし、それらを取得する方法が見つかりません。
どんな助けでも大歓迎です。
c++ - 異なるコンパイラ バージョンでの C++ DLL の使用
この質問は、「VS バージョン間で一貫性のある dll バイナリを作成する方法」に関連しています。
- VC6 で構築されたアプリケーションと DLL と、VC9 で構築された新しいアプリケーションがあります。VC9 アプリは VC6 でコンパイルされた DLL を使用する必要があり、そのほとんどは C で記述され、1 つが C++ で記述されています。
- C++ ライブラリは、名前の装飾/マングリングの問題により問題があります。
- いくつかの副作用があるように見えるため、VC9 ですべてをコンパイルすることは現在のオプションではありません。これらを解決するには、かなりの時間がかかります。
- C++ ライブラリを変更できますが、VC6 でコンパイルする必要があります。
- C++ ライブラリは、本質的に別の C ライブラリの OO ラッパーです。VC9-app は、いくつかの非静的関数だけでなく、いくつかの静的関数も使用します。
静的関数は次のようなもので処理できますが
非静的メソッドではそれほど簡単ではありません。
私が理解しているように、COM のようなインターフェイスを使用するというChris Becke の提案は役に立ちません。なぜなら、インターフェイス メンバー名はまだ修飾されているため、別のコンパイラで作成されたバイナリからはアクセスできないからです。私はそこにいますか?
唯一の解決策は、オブジェクトへのハンドラーを使用して C スタイルの DLL インターフェイスを作成することですか、それとも何か不足していますか? その場合、おそらく、ラップされた C ライブラリを直接使用する方が労力がかからないでしょう。
c++ - 装飾名の変更-VS6.0からVS2005への移行
グーグルで数時間過ごした後、専門家に聞いてみる時が来たと思います。VS 2005に移植しようとしているレガシーモジュール(MS Visual C ++ 6.0)があります。多数の呼び出し元アプリケーションが存在するため、可能であれば、これらの下位互換性を維持しようとしています。
コード的には、これは非常に簡単で、数時間の開発ですべてのコンパイラエラーとほとんどの警告が排除されました。
次に、リンク手順でいくつかの「未解決の外部シンボル」エラーに遭遇しました。これは、装飾された名前の微妙な違いのようです。
1セットのエラーは、time_tがVS2005の64ビット構造であることに関連していることが判明しました_USE_32BIT_TIME_T
。これらの3つを修正しました。
今、私は残りの2つのエラーで立ち往生しています:
関数は次のように定義されます
int RC_STATE::my_function(UINT stateId, UINT period, UINT index, UINT paramtype, UINT dpindex, UINT managerId, UINT calctype, UINT status, double *p_val, long *p_isc, CTime *p_time)
「古い」VisualStudioの下では、装飾された名前に満足していたようです
?my_function@RC_STATE@@QAEHIIIIIIIIPANPAJPAVCTime@@@Z
しかし今、VS2005は「CTime」パラメータにATL名前空間を含めたいと考えています。
?my_function@RC_STATE@@QAEHIIIIIIIIPANPAJPAVCTime@ATL@@@Z
この新しい装飾された名前で.DEFファイルを更新すると、コンパイルとリンクが行われます...やった!そのDLLを、以前は機能していたコードで削除するとすぐに、DLL内にプロシージャのエントリポイント(つまり、「古い」構造で名前空間がないもの)が見つからないと文句を言います。
助言がありますか?装飾された名前に名前空間を入れないようにコンパイラに指示できる、ある種のキーワード、コンパイラ指令はありますか(名前空間は良いことは知っていますが、名前空間を必要とするCTimeタイプとの競合はありません競合を解決します)。
装飾された名前を古い形式と一致させるための回避策はありますか?
どんな提案にも前もって感謝します。
c++ - C++ ダイナミック ライブラリとのコンパイラ間の非互換性の問題を解消する
...、これのフォローアップ。
参照された質問に対する回答から、次のことを学びました。
- 異なるコンパイラは異なる名前装飾を使用するため、コンパイラ A でビルドされた C++ ダイナミック ライブラリをコンパイラ B でビルドされたプロジェクトで使用することはできません。
- ライブラリは、プロジェクトに n 個のヘッダーとソース ファイルを含めたり、シンボルをエクスポートしたりする静的保存としてビルドできます。(別のコンパイラで使用するためにライブラリを再構築しても保存されません。)
言われていることを踏まえてSDLを詳しく見てみると、そのリンクには2つのレイヤーがあることに気付きました。私のSDLプロジェクトでは、libSDL.aに対して静的にリンクし、次にlibSDL.aがSDLに対して動的にリンクします。 dll を使用することで、コンパイラごとに異なる .dll バージョンを用意する必要がなくなります。
問題は、これが本当に事実であり、問題に対する実行可能な解決策であるかどうか、または何か (そして何が) 不足しているのかということです。
visual-c++ - Visual C ++ DLLからアンマネージクラスをエクスポートしますか?
Visual C ++ 2008でDLLを作成する場合、いくつかの選択肢があります。「クラスライブラリ」を作成できます。これにより、C ++のCLI(マネージ)拡張を使用する.Netライブラリが実際に提供されることを理解しています。
それは望ましくなく、別のVisual C ++ Windows実行可能プロジェクトにリンクするには静的な.LIBファイルが必要であると想定したため、代わりに「Win32プロジェクト」を選択し、[アプリケーション設定]パネルでC ++(MFCなし)を指定します。 )DLL。
これにより、 「DLLアプリケーション用にエクスポートされた関数」を定義する場所となる.cppファイルを使用してプロジェクトが作成されます。
これも私が望んでいることではないようです。基本的に、私が探しているのは、C#.NETではクラスライブラリアセンブリであるものと同等のネイティブC++です。いくつかのクラスをDLLにパッケージ化してから、.EXEプロジェクトにDLLプロジェクトヘッダーファイルをインクルードしてDLLのクラスを使用させ、.LIBとリンクして参照を解決したいと思います。
これを行う通常の方法は何ですか?