2016-08-12 16 views
1

私は純粋なC-st usbライブラリのプロジェクトを持っています。これをC++に移行し、同じ構造をクラスに変更する必要があります。 (HALライブラリを除く)私は.cpp.cからすべてのファイルの拡張子を変更しCをC++に移植する(埋め込み)

#ifdef __cplusplus 
extern "C" { 
#endif 

#ifdef __cplusplus 
} 
#endif 

:私のようなすべてのC++ "保護" を削除しました。 私はC++ .hexが7kBより小さく、次に.hexであることに気付きました。 .mapファイルを調べると、多くの機能が不足していることがわかりました。私はstatic関数がそれを引き起こしたと思ったが、staticキーワードを削除することは役に立たなかった。誰かが何らかの機能がコンパイルされていない原因になるか考えている人はいますか?拡張機能が.cの場合はすべて問題ありません。

+1

単なるレコード用:コンパイラとリンカの場合、ファイル拡張子は無関係です。 –

+0

興味深いことがいくつかあります:合計サイズに比べて7kB小さいですか?関数定義を失っただけでしたか、ソフトウェアで失われた機能ですか? –

+1

Cで30kB、C++で23kB。私は機能を失った。 cでコンパイルされると、PCは自分のデバイスを認識しますが、C++でコンパイルされてもそれは認識しません。 – legier

答えて

1

C++関数にはC関数とは異なるシグネチャが与えられています。機能が失われ、コードがはるかに小さいので、Cリンケージを必要とする関数がC++としてコンパイルされており、シグネチャの不一致が適切なリンクを妨げている可能性があります。

これが起こる可能性が高いのは、割り込みベクタテーブルです。ハンドラ関数がC++リンケージでコンパイルされている場合、ハンドラアドレスはCでコンパイルされたテーブルには入れません。

割り込みベクタをダブルチェックし、それらが正しい関数を参照していることを確認してください。それらが正しい場合は、C++でコンパイルされた外部シンボルを参照するかもしれない、Cでコンパイルされた他のコードを調べてください。

2

私は2つの主な理由を考えることができます。

  1. インライン化。コンパイラは、すべての用途をインライン化できる場合、スタンドアロン関数として関数を発行する必要はないと判断できます。
  2. 未使用のコード。コンパイラは、関数がコード内のどこでも使用されておらず、最終結果から関数を削除することを決定することができます。

結果があなたのコードで明示的に呼び出されることなく特定の関数を呼び出すライブラリの並べ替えとして使用される場合、最良の方法は、コードをライブラリとしてコンパイルしてリンクすることですおそらくダイナミックなlib)、それらの関数をライブラリインターフェイス(MSVCのgcc、dllexportの可視性)としてエクスポートすると、コンパイラ/リンカは、現在必要な理由がわからなくても生成されたバイナリにそれらを含めるよう強制します。

もう一つの選択肢は、デッドコードを除去するための特定のコンパイラ/リンカー最適化をオフにして、インライン関数のスタンドアロン関数インスタンスを強制的に発行することですが、非常に間接的なアプローチであり、後に保守を複雑にする可能性があります。

関連する問題