渋谷ほととぎす通信

新しいこと、枯れたこと問わず大庭が興味を持ったものを調査、生活の効率を求める完全趣味の技術ブログ。基礎を大事にしています。

C#からC++(DLL)に文字列を渡す


C++でDLLファイルを作り、それをC#から関数を呼び、C++側に文字列を渡すということをやります。

環境

  • VisualStudioCommunity2017 v15.9.8

今回作るもの

C++製のTestDll.dllというDLLファイルを作成し引数が文字列のTestメソッドを用意します。 C#側から文字列を引き渡してログを出力し、C++とC#間の文字列を引き渡すテストを行います。

DLLプロジェクトを作成

新しいプロジェクトを作成し、Visual C++ > Windowsデスクトップ > ダイナミックリンクライブラリ(DLL)を選びます。
f:id:esakun:20190319094340p:plain:w500

プロジェクトを作るとデフォルトでファイルがいくつか作られます。

f:id:esakun:20190319094910p:plain

C#側に公開する関数のアトリビュートの定義

gist.github.com

プロジェクト作成時に自動的に作られる、stdafx.hにDLLをExportするためのDllExportというマクロを定義しています。

#define DllExport extern "C" __declspec(dllexport)

参考

なぜextern "C"をつけるのか?

これは、C++コンパイル時にメソッド名が変わってしまうのを防ぎ、リンクエラーが起こさせないためです。
extern "C"の意味: 小粋空間の記事がとても参考になりました。ありがとうございました。

C++側のコード

gist.github.com

C++側にC#から呼んでほしい関数を定義し、先程定義したDllExportマクロをくっつけます。

DLL作成

f:id:esakun:20190319193749p:plain

C++側の準備が終わったので、プロジェクトを右クリックしてビルドをクリックしてTestDll.dllを作成します。
このDLLをC#プロジェクトのexeと同階層に配置します。

C#側のコード

gist.github.com

C++側で定義した関数と同名の関数を定義し、static externをくっつけます。 [DllImport("DLLファイル名", CallingConvention = CallingConvention.Cdecl)]アトリビュートも必須です。


C#を実行すると、hogehogeと出力され、思った通りの挙動になります。 文字列の場合は、C++側はchar型のポインタで受け取ることで、C#stringを渡すことができます。


以上