必要に迫られてフォームもしくはコンソールアプリからC++のモジュールを呼び出すことになった。
が、今更C++でフォーム(コンソール)を作るのは嫌なのでC#で作ったフォームからC++のモジュールを呼び出すことにした。
まあまあめんどくさかったので以下に残しておく。
1.フォームアプリのプロジェクトを作る(C#)
普通のフォームでOK。
※コンソールアプリでも特段問題無し
2.ライブラリ側のプロジェクトを追加する
・プロジェクトのプロパティで[構成の種類]を[ダイナミックライブラリ(dll)]に変更
・出力ディレクトリを1のアプリのdebugにしておく。
※リリース時にはrelease側にした方がいいと思われる
3.ライブラリ側で以下な感じで記載
ヘッダ
// library.h
#pragma once
extern "C"
{
__declspec(dllexport) void __stdcall Test1();
}
ソース
// library.cpp
#include <iostream>
#include "library.h"
void __stdcall Test1()
{
std::cout << "Cの関数が呼び出されました(Test1)" << std::endl;
}
4.呼び出し側を記載
<using>
using System.Runtime.InteropServices;
<使用するクラス内>
[DllImport("CPP_Project1.dll")]
static extern void Test1();
<使用したいタイミングで以下をCALL>
Test1();
これで呼び出せる。
引数を渡したい場合、いろいろと気を付ける必要があるが、
とりあえず文字列を渡したいのであれば、こんな感じでできた。
C++側ヘッダ
__declspec(dllexport) void __stdcall SendData(const char *t);
C++側ソース
void __stdcall SendData(const char *t)
{
std::string _wstr = std::string(t);
std::cout << _wstr.c_str() << std::endl;
}
C#側定義
[DllImport("CPP_Project1.dll")]
static extern void SendData(string t);
C#側呼び出し
string[] fields = new string[] { "test1","test2","test3","test4" };
SendData(string.Join(",", fields));
参考を見るといろいろ気を付けるべき点が書いてあるが、今回は特定の環境でとりあえず動けばいいので今回は気にしないでおく。
※逆に上記で動かなかったら追記していく。
参考
https://qiita.com/tan-y/items/64711b244cf294d6bb9d
http://nprogram.hatenablog.com/entry/2018/05/16/213033