「C++の応用 - C Sharp DLLの使用」の版間の差分
編集の要約なし |
|||
95行目: | 95行目: | ||
== C++/CLIのラッパープロジェクトを使用する方法 == | == C++/CLIのラッパープロジェクトを使用する方法 == | ||
まず、以下に示すソースコードのC# DLLを作成する。<br> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
// CSharpDLL.cs | // CSharpDLL.cs | ||
118行目: | 119行目: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
[参照の追加] | 次に、以下に示すようなソースコードのC++/CLI DLLを作成する。<br> | ||
その時、ソリューションエクスプローラからC++/CLIプロジェクトを右クリックして[参照の追加]を選択、上記で作成したC# DLLファイルを追加する。<br> | |||
同様に、[構成プロパティ] - [C/C++] - [プリプロセッサ] - [プリプロセッサの定義] | <br> | ||
また、Visual C++のプロジェクト設定を開いて、[構成プロパティ] - [全般] - [共通言語ランタイム サポート (/clr)]に変更する。<br> | |||
同様に、[構成プロパティ] - [C/C++] - [プリプロセッサ] - [プリプロセッサの定義]項目に、<code>DLL</code>プリプロセッサを追加する。<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
// CppCLIDLL.cpp | // CppCLIDLL.cpp | ||
160行目: | 163行目: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
Visual C++ | 最後に、以下に示すようなC++のソースコードのプロジェクトを作成する。<br> | ||
その時、メニューバーから[Visual C++のプロジェクト設定]を選択して、[構成プロパティ] - [C/C++] - [全般] - [追加のインクルードディレクトリ]項目に、<br> | |||
CppCLIDLL.hが存在するディレクトリを追加する。<br> | CppCLIDLL.hが存在するディレクトリを追加する。<br> | ||
<br> | |||
同様に、[構成プロパティ] - [リンカー] - [全般] - [追加のライブラリディレクトリ]項目に、CppCLIDLL.libが存在するディレクトリを追加する。<br> | 同様に、[構成プロパティ] - [リンカー] - [全般] - [追加のライブラリディレクトリ]項目に、CppCLIDLL.libが存在するディレクトリを追加する。<br> | ||
さらに、[構成プロパティ] - [リンカー] - [入力] - [追加の依存ファイル]項目に、CppCLIDLL.libを追加する。<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
// CppEXE.cpp | // CppEXE.cpp |
2021年11月22日 (月) 15:23時点における版
概要
C++ EXEからC# DLLの関数を呼び出す方法は、幾つか方法が存在しており、各々にメリットとデメリットがある。
下記の表1に代表的な4種類の方法を示す。
表1. C++ EXEからC# DLLの関数を呼び出す方法
方法 | メリット | デメリット |
---|---|---|
C++/CLIを使う | 最も簡単 VisualStudioのIntelliSenseも使用可能 |
プロジェクトの設定で[CLIを使う]に変更する必要がある |
C# DLL側で関数をエクスポートする | [CLIを使う]に変更しなくてよいGetProcAddress 関数が使用できるため、よく知られた方法で関数を呼び出す事が出来る |
C# DLL側のソースコードが無い場合は利用できない |
C# DLL側をCOM 参照可能にする | [CLIを使う]に変更しなくてよい | C++ EXEのコード量が増えて面倒である |
C# DLLに対するC++/CLIの ラッパープロジェクトを 作成して、C++ EXEから使う |
[CLIを使う]に変更しなくてよい COMを使用しない場合において、 元のプロジェクトの設定を変更したくない場合に使用可能 |
やり方がスマートではない |
上記の表1において、C++/CLIを使う方法とC# DLL側で関数をエクスポートする方法、C++/CLIのラッパープロジェクトを作成する方法を
下記にて紹介する。
C++/CLIを使う方法
// SampleDLL.cs
namespace SampleDLL
{
public class Class1
{
public static int Sum(int a, int b)
{
return a + b;
}
}
}
Visual C++のプロジェクト設定を開いて、[共通言語ランタイム サポート (/clr)]に変更する。
// SampleEXE.cpp
#include <Windows.h>
#include <iostream>
#using "SampleDLL.dll"
using namespace SampleDLL;
int main()
{
std::cout << Class1::Sum(1, 2) << std::endl;
return 0;
}
C# DLL側で関数をエクスポートする方法
まず、プロジェクトを作成してソースコードを記述する。
// SampleDLL.cs
namespace SampleDLL
{
public class Class1
{
[DllExport]
public static int Sum(int a, int b)
{
return a + b;
}
}
}
// SampleEXE.cpp
#include <Windows.h>
#include <iostream>
typedef int (*Sum)(int a, int b);
int main()
{
auto hModule = LoadLibrary(L"DllExportTest.dll");
auto sum = reinterpret_cast<Sum>(GetProcAddress(hModule, "Sum"));
std::cout << sum(1, 2) << std::endl;
return 0;
}
次に、DllExport.batをダウンロードして、DllExport.batをC# DLLのslnファイルと同じ階層に配置する。
続いて、コマンドプロンプトを開いて以下のコマンドを実行して、.NET DLLExportを起動する。
DllExport.bat -action Configure
.NET DLLExportダイアログにて、[Installed]チェックボックスにチェックを入力して、[Apply]ボタンを押下する。
最後に、C# DLLのプロジェクトをリビルドすると、作成した関数がエクスポートされる。
C++/CLIのラッパープロジェクトを使用する方法
まず、以下に示すソースコードのC# DLLを作成する。
// CSharpDLL.cs
namespace CSharpDLL
{
public static class CSharpDLLClass
{
public static void ShowValue(ref int value)
{
DialogResult result = MessageBox.Show("C# Message Box", "C# Message Box", MessageBoxButtons.OKCancel);
if (result == DialogResult.OK)
{
value = 1;
}
else
{
value = 2;
}
return;
}
}
}
次に、以下に示すようなソースコードのC++/CLI DLLを作成する。
その時、ソリューションエクスプローラからC++/CLIプロジェクトを右クリックして[参照の追加]を選択、上記で作成したC# DLLファイルを追加する。
また、Visual C++のプロジェクト設定を開いて、[構成プロパティ] - [全般] - [共通言語ランタイム サポート (/clr)]に変更する。
同様に、[構成プロパティ] - [C/C++] - [プリプロセッサ] - [プリプロセッサの定義]項目に、DLL
プリプロセッサを追加する。
// CppCLIDLL.cpp
#include "stdafx.h"
#include "CppCLIDLL.h"
using namespace System;
using namespace System::Reflection;
using namespace CSharpDLL;
namespace CppCLIDll
{
public ref class CppCLIClass
{
public:void ShowCSharpMessageBox(int *value)
{
CSharpDLLClass::ShowValue(*value);
return;
}
};
}
void ShowMessageBox(int *value)
{
CppCLIDll::CppCLIClass clsCLI;
clsCLI.ShowCSharpMessageBox(value);
}
// CppCLIDLL.h
#pragma once
#ifdef DLL
__declspec(dllexport) void ShowMessageBox(int *value);
#else
__declspec(dllimport) void ShowMessageBox(int *value);
#endif
最後に、以下に示すようなC++のソースコードのプロジェクトを作成する。
その時、メニューバーから[Visual C++のプロジェクト設定]を選択して、[構成プロパティ] - [C/C++] - [全般] - [追加のインクルードディレクトリ]項目に、
CppCLIDLL.hが存在するディレクトリを追加する。
同様に、[構成プロパティ] - [リンカー] - [全般] - [追加のライブラリディレクトリ]項目に、CppCLIDLL.libが存在するディレクトリを追加する。
さらに、[構成プロパティ] - [リンカー] - [入力] - [追加の依存ファイル]項目に、CppCLIDLL.libを追加する。
// CppEXE.cpp
#include "stdafx.h"
#include <windows.h>
#include "TestApp.h"
#include "CppCLI.h"
int _tmain()
{
int result = 0;
ShowMessageBox(&result);
if (result == 1)
{
printf("Ok Was Pressed \n");
printf("%d\n", result);
}
else if (result == 2)
{
printf("Cancel Was Pressed \n");
printf("%d\n", result);
}
else
{
printf("Unknown result \n");
}
system("pause");
return 0;
}
デバッグ
C++プロジェクトからC#プロジェクトに対するデバッグを有効にする手順を記載する。
- [ソリューションエクスプローラー]に表示されているC++プロジェクトを右クリックして、[プロパティ]を選択する。
- [<プロジェクト名> プロパティページ]画面にて、[構成プロパティ] - [デバッグ]を選択する。
- [デバッガーの種類]項目を、[混合]または[自動]に設定して、[OK]ボタンを押下する。