TadaoYamaokaの日記

山岡忠夫Homeで公開しているプログラムの開発ネタを中心に書いていきます。

LinuxでC#からC++で作成した共有ライブラリを呼び出す

cmakeでC++の共有ライブラリプロジェクトを作成する

CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(SampleDll)

enable_language(CXX)
add_library(SampleDll SHARED
  sample_dll.cpp
)


sample_dll.cppに、C++で処理を記述する。
Windowsでも使えるように、ディレクティブを使用している。

sample_dll.cpp
#include <iostream>

#ifdef _MSC_VER
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif

extern "C" {
	DLL_EXPORT DLL_EXPORT int Add(int n1, int n2);
}

DLL_EXPORT int Add(int n1, int n2)
{
	std::cout << n1 << "," << n2 << std::endl;
	return n1 + n2;
}

ビルドする

mkdir build
cd build
cmake ..
make

ビルドに成功するとlibSampleDll.soが作成される。

共有ライブラリを使用可能にする

Ubuntuの共有ライブラリの格納パスは、/etc/ld.so.conf.d/libc.confに以下の通り設定されている。

# libc default configuration
/usr/local/lib

したがって、共有ライブラリを/usr/local/libにコピーする。

cp libSampleDll.so /usr/local/lib/

ただし、このままではロードできない。
キャッシュの更新が必要なため、ldconfigコマンドを実行する。

ldconfig

以上で、共有ライブラリが使用可能となる。

.NET CoreでC#のプロジェクトを作成する

dotnet new console

共有ライブラリを呼び出すコードを記述する。

Program.cs
using System;
using System.Runtime.InteropServices;

namespace Sample
{
    class Program
    {
        [DllImport("SampleDll")]
        extern static int Add(int n1, int n2);

        static void Main(string[] args)
        {
            int a = Add(1, 2);
            Console.WriteLine(a);
        }
    }
}

共有ライブラリの名前には接頭辞の「lib」と、拡張子の「.so」は含める必要はない。

実行する

dotnet run

成功すれば以下の通り表示される。

1,2
3


GitHubソースコードを公開しました。
GitHub - TadaoYamaoka/csnative

また、Google Colabでノートブックを公開しました。
https://colab.research.google.com/drive/15Yr-JeYuUJUa08jsDPOI3BUOBMxX3Rh-