1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C++ Tips

Last updated at Posted at 2025-01-06

c言語オブジェクトをc++のコードにリンクさせる

以下をmain.cppにリンクさせる

libmyprint.c
#include <stdio.h>
#include "libmyprint.h"

void print(void)
{
	printf("This is libmyprint\n");
}

libmyprint.h
#pragma once
void print(void);

NG

main.cpp
#include <iostream>
#include "libmyprint.h"

using namespace std;

int main()
{
	cout << "This is main" << endl;
	print();
	return 0;
}

ビルドすると以下のエラーが出る

$ gcc -c libmyprint.c -Wall
$ g++ -c main.cpp -Wall
$ g++ main.o libmyprint.o -o main
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x34): undefined reference to `print()'
collect2: error: ld returned 1 exit status

main.o内にprintというシンボルがないから
※C++コンパイラが名前マングリングを行い、print→_Z5printvへシンボルが変わってる

$ nm *.o

libmyprint.o:
0000000000000000 T print
                 U puts

main.o:
                 U __cxa_atexit
                 U __dso_handle
                 U _GLOBAL_OFFSET_TABLE_
0000000000000095 t _GLOBAL__sub_I_main
0000000000000000 T main
000000000000003f t _Z41__static_initialization_and_destruction_0ii
                 U _Z5printv
                 U _ZNSolsEPFRSoS_E
                 U _ZNSt8ios_base4InitC1Ev
                 U _ZNSt8ios_base4InitD1Ev
                 U _ZSt4cout
                 U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
0000000000000000 b _ZStL8__ioinit
                 U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc

OK

extern "C" {}で、関数プロトタイプ宣言を囲む
※C++から呼び出させるモジュールをCリンケージに登録

main.cpp
#include <iostream>
extern "C"
{
#include "libmyprint.h"
}

using namespace std;

int main()
{
	cout << "This is main" << endl;
	print();
	return 0;
}

C++コンパイラの場合のみ、有効にする場合は以下。

main.cpp
#include <iostream>

#ifdef __cplusplus
extern "C"
{
#include "libmyprint.h"
}
#else
#include "libmyprint.h"
#endif

using namespace std;

int main()
{
	cout << "This is main" << endl;
	print();
	return 0;
}

ビルド通る

$ gcc -c libmyprint.c -Wall
$ g++ -c main.cpp -Wall
$ g++ main.o libmyprint.o -o main
$ ./main 
This is main
This is libmyprint

main.oにprintというシンボルがあるから

$ nm *.o

libmyprint.o:
0000000000000000 T print ★
                 U puts

main.o:
                 U __cxa_atexit
                 U __dso_handle
                 U _GLOBAL_OFFSET_TABLE_
0000000000000095 t _GLOBAL__sub_I_main
0000000000000000 T main
                 U print ★
000000000000003f t _Z41__static_initialization_and_destruction_0ii
                 U _ZNSolsEPFRSoS_E
                 U _ZNSt8ios_base4InitC1Ev
                 U _ZNSt8ios_base4InitD1Ev
                 U _ZSt4cout
                 U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
0000000000000000 b _ZStL8__ioinit
                 U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?