0

理由がわかりませんが、未定義の参照エラーが発生します。

したがって、静的ライブラリを作成する2つのファイルがあります:keyboard_input.c、keyboard_input.h

.h ファイルの内容は次のとおりです。

#ifndef __MOD_KBINPUT__
#define __MOD_KBINPUT__

int kbInit();
int kbWait();

int kbTest();

#endif

CMakeLists.txt ファイルは次のようになります。

FILE(
GLOB_RECURSE
sources
*.c
)
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include/utils/kbreader")
ADD_LIBRARY(keyboardReader ${sources})

この lib をコンパイルすると、いくつかの警告が表示されます。

src/utils/kbreader/keyboard_input.c: In function ‘kbInit’:
src/utils/kbreader/keyboard_input.c:13:14: warning: assignment from incompatible pointer type [enabled by default]
src/utils/kbreader/keyboard_input.c: In function ‘kbWait’:
src/utils/kbreader/keyboard_input.c:21:55: warning: passing argument 4 of ‘fread’ from  incompatible pointer type [enabled by default]
/usr/include/stdio.h:708:15: note: expected ‘struct FILE * __restrict__’ but argument is of type ‘struct FILE *’

次に、メインの実行可能ファイル (main.cpp) について:

#include <keyboard_input.h>
int main()
{
  kbTest();
  return 0;
}

次の CMakeLists.txt ファイルによって処理されます。

include_directories("${PROJECT_SOURCE_DIR}/include/utils/kbreader")

file(
    GLOB_RECURSE
    srcs
    *.cpp
)

add_executable(
    PEM
    ${srcs}
)
target_link_libraries(PEM keyboardReader)

そのエラーが発生してしまいます:

CMakeFiles/PEM.dir/main.cpp.o: In function `main':
main.cpp:(.text+0xb): undefined reference to `kbTest()'
collect2: ld returned 1 exit status
make[2]: *** [src/PEM/main2/PEM] Error 1
make[1]: *** [src/PEM/main2/CMakeFiles/PEM.dir/all] Error 2

libkeyboardReader.a が作成され、kbTest() 関数は何もしません。

{return 0; }

ヘッダー ファイルに kbTest() の定義を設定すると、機能します。

しかし、次のように入力すると、得られないものがあります: make keyboardReader ここに出力があります:

[ 73%] Building C object src/utils/kbreader/CMakeFiles/KeyboardReader.dir/keyboard_input.c.o
[Warning explained above]
Linking C static library ../../../lib/libKeyboardReader.a

何か問題がありますか?メモのエラー メッセージにより、lib で keyboard_input.c ファイルが省略されますか?

4

1 に答える 1

3

C ファイルと C++ ファイルを混在させています。これを機能させるには、ヘッダー ファイルを次のように変更して、C 関数を呼び出していることを C++ コンパイラに伝える必要があります。

#ifndef MOD_KBINPUT
#define MOD_KBINPUT
/* note I also fixed the macro so you aren't using a system-reserved name */

#if __cplusplus
/* this is the important part */
extern "C" {
#endif

int kbInit();
int kbWait();

int kbTest();

#if __cplusplus
}
#endif

#endif

それ以外の場合、C++ コンパイラは、関数に C++ 内部名 (シグネチャ内のすべての型情報をエンコードします。これにより、リンカーはオーバーロードされた関数を区別できます) が与えられると想定し、リンカーはそれを見つけません。

于 2012-07-20T13:45:58.813 に答える