ページ「LattepandaにDebian9.9をインストール」と「C♯のモジュールからC++のDLLを呼び出してみる」の間の差分

提供: とある社畜の頭脳整理
(ページ間の差分)
ナビゲーションに移動 検索に移動
 
 
1行目: 1行目:
<amp/>
+
久しぶりにやったら、すっかり忘れていたので覚書…
使用したLattepandaは「4G/64G」です。
 
「2G/32G」の場合、UEFIが32bitの場合があるそうです(「最近出荷されたものは64bitになっている」とフォーラムには記載されていました<ref name="LP_forum_32or64" />)。
 
その場合は、別途対応が必要になります。
 
  
= Debian9.9のダウンロード =
+
== C++のDLLプロジェクト作成 ==
== イメージの選択1 ==
+
まず、C++のDLLを作成するときの注意点…
まずは[http://www.mediawiki.org/wiki/MediaWiki/ja Debianのサイト]に行って、「ネットワークインストール」または「CD/USB ISOイメージ」をクリックする。(ネットワークが接続できる環境であれば前者、スタンドアロン?であれば後者を選択)<br/><br/>…って言っても、スタンドアロンでインストールしたこと無い…<br/><br/>[[ファイル:Debian-install-1.png | 400px]]<br/><br/>(以降は「ネットワークインストール」を選択した前提で…)<br/><br/>
+
作成するプロジェクトは、「Win32プロジェクト」を選択するんだ。<br/>
 +
[[ファイル:CShapeToCppDll-005.jpg]]
  
== イメージの選択2 ==
 
LattepandaのCPUはAtom(intel系)なので次の画面では「小さなCDまたはUSBメモリ」の「amd64」をクリックしてISOファイルをダウンロードする。<br/>(amdになっているのは気にしない…)<br/>
 
[[ファイル:Debian-install-2.png | 400px]]
 
  
= インストールメディアの準備 =
+
あと…アプリケーションの設定では「DLL」と「空のプロジェクト」を選択してね。<br/>
今回はインストールメディアにUSBメモリを使用しました。
+
[[ファイル:CShapeToCppDll-001.jpg]]<br/>
# ISOファイルをUSBに展開する<br/>適切な表現かどうかはおいといて…ISOファイルをUSBに展開する。<br/>私の場合、WindowsPCでツールを使用した。ツールは「Rufus」を使用しました。<br/>(手元にツールが無いので説明は割愛します…ググってください…すみません…)<br/><br/>
 
# Lattepandaに差し込む<br/>USBポートが3つあるのはありがたい(他2つにはキーボードとマウスをつなぐ)
 
  
= UEFIの設定の確認 =
 
イメージ取れてないので、いつか更新します(写真になりますが…)。<br/>私の場合はブートデバイスの設定以外は問題ありませんでした…。<br/>(LattepandaのドキュメントにBIOSのアップデートと載っていますが…やらなくても問題なさそうです…)<br/>最低確認しなければならないのは…<br/>「セキュアブートが無効になっていること(Debian9.9はセキュアブートに対応していない)」<br/>「ファストブートが無効になっていること」<br/>「ブートデバイスの順番をUSBメモリ→eMMCに変更する」の3つです。
 
  
== 電源の投入 ==
+
空のプロジェクトが作成されたら「cpp」「h」「def」ファイルを追加するんだ。今回は「CppDll.cpp」「CppDll.h」「CppDll.def」を追加したよ。
Lattepandaのドキュメントにも記載されていますが、USB電源を接続後、「赤のランプが消えてから」電源ボタンを長押しします。<br/><br/>
 
  
== UEFIのメニューに入る ==
 
UEFIのメニューに入るには、パンダのロゴが出る前から「delキー」を連打してください。<br/>
 
すると以下のような画面が表示されます。<br/>
 
[[ファイル:Debian-install-050.png | 400px]]
 
  
== セキュアブートの無効化確認 ==
+
そしたら、プロジェクトのプロパティを開いて「構成プロパティ→リンカー→入力→モジュール定義ファイル」に「CppDll.def」を設定するんだ。<br/>
左右の矢印キーを使用して、画面上部のタブから「Security」を選択します。<br/>
+
(DebugとReleaseでそれぞれ設定する必要があるんだよ。)<br/>
[[ファイル:Debian-install-053.png | 400px]]<br/>
+
[[ファイル:CShapeToCppDll-002.jpg]]<br/>
そこから上下の矢印キーを使用して「Secure Boot menu」を選択状態にして、Enterキーを押します。<br/>
 
すると、以下のような画面が表示されます。<br/>
 
[[ファイル:Debian-install-055.png | 400px]]<br/>
 
この画面で「Secure Boot(画像見づらくてスミマセン…)」が「Disabled」になっていることを確認します<br/>
 
もしなっていない場合は、上下の矢印キーで「Secure Boot」まで移動してEnterキーを押し、「Disabled」を選択します。
 
  
== ファストブートの無効化確認 ==
+
== DLLのコード ==
左右の矢印キーを使用して、画面上部のタブから「Boot」を選択します。<br/>
+
=== ヘッダーファイル(*.h) ===
[[ファイル:Debian-install-054.png | 400px]]<br/>
+
<syntaxhighlight lang="cpp">
「Fast Boot」の項目が「Disabled」になっていることを確認します。<br/>
+
#ifndef DLLAPI
もしなっていない場合は、上下の矢印キーで「Fast Boot」まで移動してEnterキーを押し、「Disabled」を選択します。
+
#define DLLAPI extern "C" __declspec(dllimport)
 +
#endif
  
== ブートデバイスの順番の変更 ==
+
DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2);
左右の矢印キーを使用して、画面上部のタブから「Boot」を選択します。<br/>
+
</syntaxhighlight>
[[ファイル:Debian-install-054.png | 400px]]<br/>
 
画面下部の「Boot Option Priorities」で、(サンプル画面には出ていませんが…)<br/>「#1」をUSBデバイス、「#2」をeMMC(もしかしたら「Windows10」とか表示されているかもです)に変更します。
 
  
== 保存してメニューを終了する ==
+
=== コードファイル(*.cpp) ===
メニューから「save and exit」を選択、または「PF4キー」を押し、「Yes/No」で「Yes」を選択
+
<syntaxhighlight lang="cpp">
 +
#define DLLAPI
  
= Debian9.9のインストール =
+
#include "CppDll.h"
LattepandaのUEFIメニューを抜けるとインストール画面が表示されます。
 
  
== 初期設定? ==
+
DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2)
# インストール方法?の選択<br/>「Graphical Install」か「Install」を選択します。<br/>どちらも入力項目は同じです。ここでは「Install」を選択した場合を説明していきます<br/>[[ファイル:debian-install-101.png | 400px]]<br/><br/>
+
{
# 言語の選択<br/>使用する言語を選択します。<br/>このサイトを見ている人は、おそらく日本人なのでほとんどの人は「Japanese - 日本語」を選択します。<br/>[[ファイル:debian-install-102.png | 400px]]<br/><br/>
+
return p_Number1 + p_Number2;
# 場所の選択<br/>住んでいる場所を選択します。多分、時間の設定に関わる選択です。<br/>[[ファイル:debian-install-103.png | 400px]]<br/><br/>
+
}
# キーボードの設定<br/>日本語キーボード(いわゆる109キーボード)を使用している人は、「日本語」を選択します。<br/>それ以外の英語キーボード等を使用している人は、該当するキーボード?を選択してください。<br/>[[ファイル:debian-install-104.png | 400px]]
+
</syntaxhighlight>
  
== ネットワークの設定 ==
+
=== モジュール定義ファイル(*.def) ===
# ホスト名の設定<br/>ホスト名(Windowsで言うところのコンピューター名)を入力します。<br/>デフォルトで問題ない場合は、そのままエンターキーを押します。<br/>[[ファイル:debian-install-105.png | 400px]]<br/><br/>
+
<syntaxhighlight lang="text">
# ドメイン名の設定<br/>ドメイン名を入力します。外部に公開する人以外は、空白で問題ありません。<br/>外部に公開する人は…取得したドメイン名を入れるのかな?<br/>[[ファイル:debian-install-106.png | 400px]]
+
LIBRARY CppDll
  
== ユーザーとパスワードのセットアップ ==
+
EXPORTS
# rootユーザーのパスワード設定<br/>rootユーザーのパスワードを入力します。<br/>画面にも書かれていますが、何も入力しないと、後で設定するユーザーに「sudo」権限が付与されます(正確には「sudo」ユーザグループに追加される)。<br/>入力した場合は絶対に忘れないようにしましょう。<br/>また、rootユーザーはすべての権限が付与されているユーザーです。安易なパスワードを設定して、不正にログインされないようにしましょう。[[ファイル:debian-install-107.png | 400px]]<br/><br/>
+
_Sum
# rootユーザーのパスワード再入力<br/>rootユーザーのパスワードを再入力します。<br/>全画面で入力しなかったときは、ここでも入力せずにエンターキーを押します。<br/>[[ファイル:debian-install-108.png | 400px]]<br/><br/>
+
</syntaxhighlight>
# 新しいユーザーのフルネーム設定<br/>新しいユーザーの本名(フルネーム)を入力します。<br/>ここで入力するフルネームは、ログイン画面で表示される文字列になります(ログインユーザーではありません。あくまでも表示だけです)。<br/>フルネームと言っても真面目にフルネームを入力する必要はありません。<br/>ニックネームなどでOKです。<br/>[[ファイル:debian-install-109.png | 400px]]<br/><br/>
 
# 新しいユーザーのアカウント名設定<br/>あなたのアカウントのユーザー名を入力します。<br/>いわゆるログインユーザー名です。<br/>[[ファイル:debian-install-110.png | 400px]]<br/><br/>
 
# 新しいユーザーのパスワード設定<br/>新しいユーザーのパスワードを入力します。<br/>ログインパスワードになります。<br/>パスワードを忘れても、rootのパスワードを覚えていればどうにかなりますが…<br/>rootのパスワードを設定しなかった場合は、このユーザーがrootと同等の権限を持つことになります。<br/>rootのパスワードと同様に、忘れないように、また安易なパスワードを設定しなようにしましょう。<br/>[[ファイル:debian-install-111.png | 400px]]<br/><br/>
 
# 新しいユーザーのパスワード再入力<br/>パスワードを再入力します。<br/>[[ファイル:debian-install-112.png | 400px]]<br/><br/>
 
  
== ディスクのパーティショニング ==
+
== C♯のプロジェクト作成 ==
# LVMや暗号化の設定<br/>LVMや暗号化の選択をします。<br/>よくわからない場合は「ディスク全体を使う」で良いかと思います。<br/>場合によって「空き領域全体を使う」という選択肢が表示されます。<br/>マルチブートを使用しない限りは「ディスク全体を使う」で問題ないかと思います。<br/>LVMは複数のハードディスクにまたがってパーティションを作成できる機能…みたいです。<br/>LattepandaのeMMC(いわゆる内臓ディスク)だけにインストールする場合は、「ディスク全体を使う」を選択することになります。<br/>(やらなかったけど…これ、外付けHDDをつないでたらLVMで1つのパーティションにできたのかな?)<br/>暗号化はその名のとおりです。<br/>[[ファイル:debian-install-113.png | 400px]]<br/><br/>
+
ほとんどそのまま作るんだけど…ソリューションのコンパイル対策をしておくよ。
# ディスクの選択<br/>パーティショニングするディスクを選択します。<br/>下のイメージでは1つしか表示されていませんが、LattepandaにUSBメモリを刺してインストールしていると、eMMCとUSBメモリの2つが表示されます。<br/>インストール先はeMMCです。<br/>[[ファイル:debian-install-114.png | 400px]]<br/><br/>
 
# パーティショニング機構の選択<br/>パーティショニング機構を選択します。<br/>よくわからない場合は「すべてのファイルを1つのパーティションに(初心者ユーザには推奨)」で良いかと思います。<br/>[[ファイル:debian-install-115.png | 400px]]<br/><br/>
 
# 確認1<br/>「パーティショニングの終了とディスクへの変更の書き込み」を選択します。<br/>[[ファイル:debian-install-116.png | 400px]]<br/><br/>
 
# 確認2<br/>書き込みするかの確認です。<br/>問題なければ「はい」を選択します。<br/>[[ファイル:debian-install-117.png | 400px]]
 
  
== パッケージマネージャの設定 ==
+
=== ビルドイベントの設定 ===
# DVDの検査の確認<br/>ネットワークにつながる環境なら、「いいえ」で問題ないかと思います。<br/>[[ファイル:debian-install-118.png | 400px]]<br/><br/>
+
C++のDLLはソリューションフォルダ直下の「Debug」や「Release」フォルダにDLLが格納されてしまうんだ。そうすると、デバッグするときにDLLが見つからないので、ビルドイベントを使ってコピーしてしまうよ。以下のように設定してね。(「Release」コンパイルするまでは「Release」フォルダがないのでコメントアウトしているよ)<br/>
# アーカイブミラーの地域を選択<br/>特にこだわりが無いなら「日本」で問題ないです。<br/>基本的には、住んでいる地域と同じものを選びます。<br/>[[ファイル:debian-install-119.png | 400px]]<br/><br/>
+
[[ファイル:CShapeToCppDll-004.jpg]]<br/>
# アーカイブミラーの選択<br/>特にこだわりが無ければ「ftp.jp.debian.org」で問題ないです。<br/>このアーカイブミラーは「[https://www.debian.or.jp/using/mirror.html Debian JP Project]」が運営しているミラーサイトになります。<br/>[[ファイル:debian-install-120.png | 400px]]<br/><br/>
 
# プロキシの設定<br/>プロキシ経由で外部(インターネット)にアクセスする場合は設定します。<br/>一般的な家庭においては、ほぼ関係ないはずです。<br/>(いや…Debianを設定しようとしている時点で、自前プロキシを立ててる可能性もあるか…)<br/>よくあるのですが…ユーザーIDやパスワードに「@(アットマーク)」を使用している場合は「%40」にエスケープ(書き換えて)設定します。<br/>[[ファイル:debian-install-121.png | 400px]]<br/><br/>
 
  
== popularlty-contest の設定 ==
+
=== プロジェクトの依存関係の設定 ===
# 統計の情報送信<br/>どちらでも…<br/>[[ファイル:debian-install-122.png | 400px]]<br/><br/>
+
コピーするにもちゃんとリコンパイルされた資源をコピーしないといけないので、プロジェクトの依存関係を設定することで、ビルドの順番を設定するよ。<Br/>
 +
ソリューションエクスプローラーからC♯のプロジェクトを右クリックして「ビルド依存関係」→「プロジェクト依存関係」を選択してね。<br/>
 +
「依存関係」タブの依存先にC++のプロジェクトが表示されているはずだから、チェックを入れてOKボタンをクリックしてね。
  
== ソフトウェアの選択 ==
+
== C♯のコード ==
# ソフトウェアの選択<br/>「Debian デスクトップ環境」と「標準システムユーティリティ」にチェックを付けた状態で、その他は必要に応じてソフトウェアを選択します。<br/>デスクトップは好みのものを…私は「GNOME」を選択しています。<br/>外部接続する場合は、「sshサーバー」を忘れずに…。<br/>[[ファイル:Debian-install-123.png | 400px]]
+
MVVMモデルでサンプルを作ったからビューモデルが入っているけど…DLLを呼ぶには必要ないから無視してね。
 +
=== モデル ===
 +
<syntaxhighlight lang="C#">
 +
using System;
 +
using System.Collections.Generic;
 +
using System.Linq;
 +
using System.Text;
 +
using System.Threading.Tasks;
 +
using System.Windows;
 +
using System.Windows.Controls;
 +
using System.Windows.Data;
 +
using System.Windows.Documents;
 +
using System.Windows.Input;
 +
using System.Windows.Media;
 +
using System.Windows.Media.Imaging;
 +
using System.Windows.Navigation;
 +
using System.Windows.Shapes;
  
== ハードディスクへの GRUB ブートローダーのインストール ==
+
//追加
# GRUBブートローダーをインストールするか<br/>複数のOSをインストールしている場合は注意してください。<br/>ブートローダーをインストールしていない(コンピュータを起動したときに、OSの選択画面が表示されない)場合は、「はい」を選択します。<br/>[[ファイル:Debian-install-124.png | 400px]]<br/><br/>
+
using System.Runtime.InteropServices;
# GRUBブートローダーのインストール先の選択<br/>GRUBをインストールするデバイスを選択します。<br/>画面では出ていませんが、Lattepandaであれば、「eMMC」が表示されているかと思いますので、それを選択します。<br/>[[ファイル:Debian-install-125.png | 400px]]<br/><br/>
 
  
== インストールの完了 ==
+
namespace CSharpToCDLL
# インストールの完了<br/>ここで、インストールのために刺していたUSBメモリを抜きます。<br/>抜いたらば「続ける」を選択してください。<br/>その後、自動的にマシンのクリーンアップを行った後、再起動します。<br/>[[ファイル:Debian-install-126.png | 400px]]<br/><br/>
+
{
 +
    /// <summary>
 +
    /// MainWindow.xaml の相互作用ロジック
 +
    /// </summary>
 +
    public partial class MainWindow : Window
 +
    {
 +
        /// <summary>
 +
        /// DLLの関数定義
 +
        /// </summary>
 +
        /// <param name="p_Number1">数値1</param>
 +
        /// <param name="p_Number2">数値2</param>
 +
        /// <returns>合計</returns>
 +
        [DllImport("CppDll.dll")]
 +
        private extern static Int32 _Sum(Int32 p_Number1,Int32 p_Number2);
  
= ログイン画面の表示(画面が真っ黒) =
+
        /// <summary>
さて…以下のような正しくログイン画面が表示されたでしょうか?<br/>上記の手順に従ってインストールすると、真っ黒な画面が表示されるかと思います(マウスを動かすとカーソルは見ることができます)。<br/>[[ファイル:Debian-install-127.png | 400px]]<br/><br/>慌てずに「ウインドウズキー+p」を押してみてください。<br/>ログイン画面が表示されたかと思います。<br/><br/>何がおきているかというと、LattepandaにはHDMI以外にもう一つディスプレイを接続するところがあります。<br/>そちらがプライマリディスプレイになっており、HDMIがサブディスプレイになってしまっています。<br/>UEFIで設定を変えられるのですが…設定を変更しても変わってくれません(少なくとも私の環境では…)。
+
        /// 標準のコンストラクタ
 +
        /// </summary>
 +
        public MainWindow()
 +
        {
 +
            InitializeComponent();
 +
        }
  
これが結構煩わしいので、私はGNOMEから「プライマリディスプレイを無効」にして、「ユーザーを自動ログイン」にしています。
+
        /// <summary>
 +
        /// ボタンクリックイベントハンドラ
 +
        /// </summary>
 +
        /// <param name="sender">イベント送信元</param>
 +
        /// <param name="e">イベント情報</param>
 +
        private void Button_Click(object sender, RoutedEventArgs e)
 +
        {
 +
            //DLLの関数を呼び出す
 +
            Int32 l_Result = _Sum(300, 500);
  
= 脚注 =
+
            //計算結果の表示
<references>
+
            MessageBox.Show("計算結果:" + l_Result.ToString());
<ref name="LP_forum_32or64">[http://www.lattepanda.com/topic-f6t1595.html 64 Bit Image on a 32 Bit Board? - LattePanda Forum]</ref>
+
        }
</references>
+
    }
 +
}
 +
</syntaxhighlight>
  
[[Category:Debian]]
+
=== ビュー ===
[[Category:Lattepanda]]
+
<source lang="xml">
 +
<Window x:Class="CSharpToCDLL.MainWindow"
 +
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 +
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 +
        Title="MainWindow"
 +
        Height="77.056"
 +
        Width="525">
 +
    <Grid>
 +
        <Grid.RowDefinitions>
 +
            <RowDefinition Height="5"/>
 +
            <RowDefinition Height="24"/>
 +
            <RowDefinition/>
 +
            <RowDefinition Height="5"/>
 +
        </Grid.RowDefinitions>
 +
        <Grid.ColumnDefinitions>
 +
            <ColumnDefinition Width="5"/>
 +
            <ColumnDefinition/>
 +
            <ColumnDefinition Width="5"/>
 +
            <ColumnDefinition Width="75"/>
 +
            <ColumnDefinition Width="5"/>
 +
        </Grid.ColumnDefinitions>
 +
        <Label
 +
            Grid.Row="1"
 +
            Grid.Column="1"
 +
            Content="{Binding Label_Content}"/>
 +
        <Button
 +
            Grid.Row="1"
 +
            Grid.Column="3"
 +
            Content="実行"
 +
            Click="Button_Click"/>
 +
    </Grid>
 +
</Window>
 +
</source>
 +
=== ビューモデル ===
 +
<source lang="csharp">
 +
using System;
 +
using System.Collections.Generic;
 +
using System.Linq;
 +
using System.Text;
 +
using System.Threading.Tasks;
 +
 
 +
//追加
 +
using System.ComponentModel;
 +
 
 +
namespace CSharpToCDLL
 +
{
 +
    class MainWindowViewModel : INotifyPropertyChanged
 +
    {
 +
        /// <summary>
 +
        /// ラベル表示用変数
 +
        /// </summary>
 +
        private String m_Label_Content;
 +
 
 +
        /// <summary>
 +
        /// ラベル表示文字列
 +
        /// </summary>
 +
        public String Label_Content
 +
        {
 +
            set
 +
            {
 +
                this.m_Label_Content = value;
 +
                this.OnPropertyChanged("Label_Content");
 +
            }
 +
            get { return this.m_Label_Content; }
 +
        }
 +
 
 +
        /// <summary>
 +
        /// プロパティ変更イベントハンドラ
 +
        /// </summary>
 +
        public event PropertyChangedEventHandler PropertyChanged;
 +
 
 +
        /// <summary>
 +
        /// プロパティ変更通知
 +
        /// </summary>
 +
        /// <param name="p_PropertyName">プロパティ名</param>
 +
        public void OnPropertyChanged(String p_PropertyName)
 +
        {
 +
            if (this.PropertyChanged != null)
 +
            {
 +
                this.PropertyChanged(this, new PropertyChangedEventArgs(p_PropertyName));
 +
            }
 +
        }
 +
    }
 +
}
 +
</source>
 +
 
 +
[[Category:C♯]]
 +
[[Category:C++]]
 +
[[Category:dll]]

2019年7月26日 (金) 07:46時点における版

久しぶりにやったら、すっかり忘れていたので覚書…

C++のDLLプロジェクト作成

まず、C++のDLLを作成するときの注意点… 作成するプロジェクトは、「Win32プロジェクト」を選択するんだ。
CShapeToCppDll-005.jpg


あと…アプリケーションの設定では「DLL」と「空のプロジェクト」を選択してね。
CShapeToCppDll-001.jpg


空のプロジェクトが作成されたら「cpp」「h」「def」ファイルを追加するんだ。今回は「CppDll.cpp」「CppDll.h」「CppDll.def」を追加したよ。


そしたら、プロジェクトのプロパティを開いて「構成プロパティ→リンカー→入力→モジュール定義ファイル」に「CppDll.def」を設定するんだ。
(DebugとReleaseでそれぞれ設定する必要があるんだよ。)
CShapeToCppDll-002.jpg

DLLのコード

ヘッダーファイル(*.h)

#ifndef DLLAPI
#define DLLAPI extern "C" __declspec(dllimport)
#endif

DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2);

コードファイル(*.cpp)

#define DLLAPI

#include "CppDll.h"

DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2)
{
	return p_Number1 + p_Number2;
}

モジュール定義ファイル(*.def)

LIBRARY	CppDll

EXPORTS
	_Sum

C♯のプロジェクト作成

ほとんどそのまま作るんだけど…ソリューションのコンパイル対策をしておくよ。

ビルドイベントの設定

C++のDLLはソリューションフォルダ直下の「Debug」や「Release」フォルダにDLLが格納されてしまうんだ。そうすると、デバッグするときにDLLが見つからないので、ビルドイベントを使ってコピーしてしまうよ。以下のように設定してね。(「Release」コンパイルするまでは「Release」フォルダがないのでコメントアウトしているよ)
CShapeToCppDll-004.jpg

プロジェクトの依存関係の設定

コピーするにもちゃんとリコンパイルされた資源をコピーしないといけないので、プロジェクトの依存関係を設定することで、ビルドの順番を設定するよ。
ソリューションエクスプローラーからC♯のプロジェクトを右クリックして「ビルド依存関係」→「プロジェクト依存関係」を選択してね。
「依存関係」タブの依存先にC++のプロジェクトが表示されているはずだから、チェックを入れてOKボタンをクリックしてね。

C♯のコード

MVVMモデルでサンプルを作ったからビューモデルが入っているけど…DLLを呼ぶには必要ないから無視してね。

モデル

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

//追加
using System.Runtime.InteropServices;

namespace CSharpToCDLL
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// DLLの関数定義
        /// </summary>
        /// <param name="p_Number1">数値1</param>
        /// <param name="p_Number2">数値2</param>
        /// <returns>合計</returns>
        [DllImport("CppDll.dll")]
        private extern static Int32 _Sum(Int32 p_Number1,Int32 p_Number2);

        /// <summary>
        /// 標準のコンストラクタ
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// ボタンクリックイベントハンドラ
        /// </summary>
        /// <param name="sender">イベント送信元</param>
        /// <param name="e">イベント情報</param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //DLLの関数を呼び出す
            Int32 l_Result = _Sum(300, 500);

            //計算結果の表示
            MessageBox.Show("計算結果:" + l_Result.ToString());
        }
    }
}

ビュー

<Window x:Class="CSharpToCDLL.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="77.056"
        Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="5"/>
            <RowDefinition Height="24"/>
            <RowDefinition/>
            <RowDefinition Height="5"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="75"/>
            <ColumnDefinition Width="5"/>
        </Grid.ColumnDefinitions>
        <Label
            Grid.Row="1"
            Grid.Column="1"
            Content="{Binding Label_Content}"/>
        <Button
            Grid.Row="1"
            Grid.Column="3"
            Content="実行"
            Click="Button_Click"/>
    </Grid>
</Window>

ビューモデル

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//追加
using System.ComponentModel;

namespace CSharpToCDLL
{
    class MainWindowViewModel : INotifyPropertyChanged
    {
        /// <summary>
        /// ラベル表示用変数
        /// </summary>
        private String m_Label_Content;

        /// <summary>
        /// ラベル表示文字列
        /// </summary>
        public String Label_Content
        {
            set
            {
                this.m_Label_Content = value;
                this.OnPropertyChanged("Label_Content");
            }
            get { return this.m_Label_Content; }
        }

        /// <summary>
        /// プロパティ変更イベントハンドラ
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// プロパティ変更通知
        /// </summary>
        /// <param name="p_PropertyName">プロパティ名</param>
        public void OnPropertyChanged(String p_PropertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(p_PropertyName));
            }
        }
    }
}