Problem

前回は、Visual Studio CodeからSharedライブラリを作成しました。

C#からSharedライブラリを呼び出すには、P/Invokeを使うしかありませんが、Sharedライブラリ側で関数をExportする必要があります。
Visual C++**ならdefファイルでも定義するか、シンプルにC++/CLI**を使ってクラス経由で使えるようすることも一つの手ですが、Linuxでは後者は使えません。

Solution

前回と同じように、Visual Studio CodeからCMakeでテンプレートを作成し、Sharedライブラリを生成する状態まで準備します。
この状態で生成された*.soファイルをnmコマンドを -D オプションをつけて実行することで、ライブラリに含まれるシンボルを表示してみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ nm -D libTestCMake.so
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
00000000000007ea T _Z9say_hellov
U _ZNSt8ios_base4InitC1Ev
U _ZNSt8ios_base4InitD1Ev
U _ZSt4cout
U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
0000000000201030 B __bss_start
U __cxa_atexit
w __cxa_finalize
w __gmon_start__
0000000000201030 D _edata
0000000000201038 B _end
0000000000000868 T _fini
00000000000006a8 T _init

元のソースは

1
2
3
#include <iostream>

void say_hello(){ std::cout << "Hello, from TestCMake!\n"; }

です。
シンボルにsay_helloという文字が見えます。
ですが、前後に不規則?な英数字が付与されています。

では、関数をExportしてみます。
ソースコードを下記のように修正し、ビルドした後、シンボルを表示してみます。

1
2
3
#include <iostream>

extern "C" void say_hello(){ std::cout << "Hello, from TestCMake!\n"; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ nm -D libTestCMake.so
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U _ZNSt8ios_base4InitC1Ev
U _ZNSt8ios_base4InitD1Ev
U _ZSt4cout
U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
0000000000201030 B __bss_start
U __cxa_atexit
w __cxa_finalize
w __gmon_start__
0000000000201030 D _edata
0000000000201038 B _end
0000000000000868 T _fini
00000000000006a8 T _init
00000000000007ea T say_hello

今度は、say_helloという文字列が完全に表示されています。
無事に公開されているようです。