環境:Visual Studio2017、.Net Framework4.7.2
はじめに
C言語で作成したスタティックライブラリをC#で再利用したく試行錯誤していました。
手順を備忘録としてまとめます。
こちらのサイトを参考にしています。
https://www.atmarkit.co.jp/fdotnet/special/vcppinvista01/vcppinvista01_02.html
スタティックライブラリの用意
本来であれば既にスタティックライブラリは用意されているのですが、せっかくなのでスタティックライブラリを作成するところからやっていきましょう。
プロジェクトの作成
Visual Studioを起動し、「ファイル」-「新規作成」-「プロジェクト」を選択肢し、以下のようなプロジェクトを作成します。
プロジェクトのプロパティ
こちらのサイトにもあるように、ライブラリ・DLLはReleaseで作成したほうが良さそうです。
https://qiita.com/jamjamjaaaaaam_/items/d9fe21833a69da891358
構成の種類が「スタティックライブラリ(.lib)」になっていることを確認します。
プリコンパイル済みヘッダーを「プリコンパイル済みヘッダーを使用しない」に変更します。
コードの内容
テスト用なので以下の簡単なコードを書いておきます。
Cソース
#include "stdafx.h"
int plus(int a, int b) {
return a + b;
}
ヘッダー
int plus(int a, int b);
ひとまず、スタティックライブラリは完成です。
C++/CLIでラッパーを作成する
プロジェクトの作成
ソリューションを右クリックして、「追加」-「新しいプロジェクト」を選択肢、以下のようなプロジェクトを作成します。
プロジェクトのプロパティ
以下のようにプロパティを変更します。
- 「ダイナミックライブラリ」に設定されていることを確認します。
- インクルードディレクトリにスタティックライブラリのヘッダーファイルが保存されているディレクトリを設定します。
- スタティックライブラリ(今回の場合、StaticLib.lib)が生成されるディレクトリを設定します。
- 読み込むスタティックライブラリのファイル名(StaticLib.lib)を設定します。
- プリコンパイル済みヘッダーを「プリコンパイル済みヘッダーを使用しない」に変更します。
- 「Cコードとしてコンパイル」を設定します。
コードの内容
スタティックライブラリで定義したplus関数をラッパー関数で呼び出すようにしています。
DLLEXPORT __declspec(dllexport)
を使用することで.Netアプリから呼び出すことが可能になります。
#include <Windows.h>
#include "stdafx.h"
#define DLLEXPORT __declspec(dllexport)
DLLEXPORT int __cdecl plusWrapper(int a, int b) {
return plus(a, b);
}
コンソールアプリ(.Net Framework)を作成する
ソリューションを右クリックして、「追加」-「新しいプロジェクト」を選択肢、以下のようなプロジェクトを作成します。
コードの内容
using System;
using System.Runtime.InteropServices;
namespace ConsoleApp
{
class Program
{
const string DLLNAME = "Dll.dll";
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 plusWrapper(Int32 a, Int32 b);
static void Main(string[] args)
{
var c = plusWrapper(1, 3);
Console.WriteLine(c);
Console.ReadLine();
}
}
}
まとめ
スムーズここまで作成できたわけではなく、ライブラリのバージョン、プラットフォームの違いなどを変更しながら試行錯誤していました。かなりハマりました。
情報が間違っている箇所があるかもしれません。間違いがあった場合はコメントにてご指摘ください。