2

borland C ++BuilderV5.5を使用してC++プログラムを構築しようとしています。acファイルで定義された関数を呼び出そうとするまで、すべてが正常に機能します。コンパイラはfindeは機能しますが、リンクは機能しません。リンカは、c++ファイルから呼び出された関数を見つけることができません。.objファイルは生成され、プロジェクトxmlファイルの一部です。このエラーを解決する方法を誰かに教えてください。副作用がないことを確認するために、コンストラクターでc関数呼び出しを呼び出すだけで新しいプロジェクトを開始します。プロジェクトの構造は次のようになります。

Form1.hはコンストラクターを定義し、c関数が定義されているヘッダーを含みます

Form1.cppはコンストラクターを実装し、c関数を呼び出します

test.hは、void関数 "void abc();"を定義します。

test.cにはtest.hが含まれており、void関数 "void abc(){}"を実装しています。

...unit1.objから参照される未解決の外部「abc()」

誰かアイデアがありますか?

ここにいくつかのコード

#include <vcl.h>
#pragma hdrstop
#include "Multicopter_Model.h"
#include "Unit1.h"

#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
abcdefg();
return;
}

_

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

void abcdefg();

#endif */

_

#include "Multicopter_Model.h"
/* Model initialize function */
void abcdefg()
{

}
4

3 に答える 3

3

Borland C ++について具体的には何も知りませんが、CとしてビルドされたC ++コードで何かを宣言する場合は、通常extern "C" { ... }、宣言を回避する必要があります。したがって、この場合、Multicopter_Model.hファイルは次のようになります。

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

#ifdef __cplusplus
extern "C" {
#endif

void abcdefg();

#ifdef __cplusplus
}
#endif

#endif

これは、オーバーロードなどの機能をサポートするために、C++コードから構築されたオブジェクトファイルに名前マングリングと呼ばれるものが適用されているためです。その情報をエンコードします。(注1:実際の名前マングリングの規則はより簡潔でわかりにくいです。注2:理論的には名前マングリング以外の方法でも同じことが実現できますが、実際には誰もが名前マングリングを行います。注3:コンパイラーが異なれば名前マングリングの形式も異なります。 。)したがって、C++コンパイラが次の宣言を確認した場合foointintfoo__Rint_Aintabcdefg「これは本当にCであり、C ++ではない」という魔法の注釈がないと、名前が壊れ、コンパイルされたコードは実際に(私の作成した名前マングリング規則で)呼び出される関数などを見つけることを期待しますabcdefg_Rvoid_Anone。ビルドされたCコンパイラForm1.objはC++の名前マングリングを行わないため、この関数は存在しません。そのため、リンカは探しているものを見つけることができません。

リンカのエラーメッセージに隠された手がかりが少しあります。abcdefg()だけでなく、見つからなかったと表示されていることに気付くでしょうabcdefg。これは、引数リストが探している名前にエンコードされているためです。リンカは、実際に探していた壊れた怪物ではなく、人間が読める形式の名前を親切に報告しています。

于 2012-06-14T08:11:31.587 に答える
1

C++のFAQ項目[32.4]を参照してください。自分のCヘッダーファイルを変更して、C++コードに#includeしやすくする方法を教えてください(実際にはセクション32全体を読んでください。)使用する:

#ifndef RTW_HEADER_Multicopter_Model_h_
#define RTW_HEADER_Multicopter_Model_h_

#ifdef __cplusplus
 extern "C" {
#endif 

void abcdefg();

#ifdef __cplusplus
 }
#endif 
#endif */
于 2012-06-14T08:11:25.207 に答える
0

関数のオーバーロードとオーバーライドをC++で機能させるには、すべてのC ++コンパイラが関数名に情報を追加します(http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2Bを参照)。Cはそうではないので、C ++でプロトタイプを使用している場合、生成されるシンボル名はCコンパイラによって生成されるものと同じにはなりません。

これを修正する方法については、他の回答を参照してください。

于 2012-06-14T08:14:18.397 に答える