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

提供: とある社畜の頭脳整理
(ページ間の差分)
ナビゲーションに移動 検索に移動
 
 
1行目: 1行目:
= イメージのダウンロード =
+
久しぶりにやったら、すっかり忘れていたので覚書…
先ずは「[https://www.archlinux.jp/ Arch Linux JP Project]」をブラウザで開きます。<br/>
 
以下の画面が表示されるので、右上の「ダウンロード」をクリックします。<br/>
 
[[ファイル:archlinux-install-001.png | 400px]]
 
  
 +
== C++のDLLプロジェクト作成 ==
 +
まず、C++のDLLを作成するときの注意点…
 +
作成するプロジェクトは、「Win32プロジェクト」を選択するんだ。<br/>
 +
[[ファイル:CShapeToCppDll-005.jpg]]
  
「HTTP で直接ダウンロード (推奨)」の日本のサーバーから適当なサーバーをクリックします。<br/>
 
[[ファイル:archlinux-install-002.png | 400px]]
 
  
 +
あと…アプリケーションの設定では「DLL」と「空のプロジェクト」を選択してね。<br/>
 +
[[ファイル:CShapeToCppDll-001.jpg]]<br/>
  
ディレクトリの内容が表示されたら「*.iso」ファイルをクリックして、ダウンロードします。<br/>
 
[[ファイル:archlinux-install-003.png | 400px]]
 
  
= USBの作成 =
+
空のプロジェクトが作成されたら「cpp」「h」「def」ファイルを追加するんだ。今回は「CppDll.cpp」「CppDll.h」「CppDll.def」を追加したよ。
今回はインストールメディアにUSBメモリを使用しました。
 
# ISOファイルをUSBに展開する<br/>適切な表現かどうかはおいといて…ISOファイルをUSBに展開する。<br/>私の場合、WindowsPCでツールを使用した。ツールは「Rufus」を使用しました。<br/>(手元にツールが無いので説明は割愛します…ググってください…すみません…)<br/><br/>
 
# Lattepandaに差し込む<br/>USBポートが3つあるのはありがたい(他2つにはキーボードとマウスをつなぐ)
 
  
= UEFIの設定確認 =
 
インストールを開始する前に、UEFIの設定を確認します。<br/>
 
Latttepamda起動時に「Deleteキー」を連打して、UEFIのメニューに入ります。<br/>
 
  
== セキュアブートの無効化 ==
+
そしたら、プロジェクトのプロパティを開いて「構成プロパティ→リンカー→入力→モジュール定義ファイル」に「CppDll.def」を設定するんだ。<br/>
セキュアブートはLinuxの世界ではまだ一般的では無いと思うので、セキュアブートを使用しない方向でインストールしていきます。<br/>
+
(DebugとReleaseでそれぞれ設定する必要があるんだよ。)<br/>
UEFIメニューで「Security」を選択します。<br/>
+
[[ファイル:CShapeToCppDll-002.jpg]]<br/>
[[ファイル:archlinux-install-101.png | 400px]]
 
  
 +
== DLLのコード ==
 +
=== ヘッダーファイル(*.h) ===
 +
<syntaxhighlight lang="cpp">
 +
#ifndef DLLAPI
 +
#define DLLAPI extern "C" __declspec(dllimport)
 +
#endif
  
「Security」画面で「Secure Boot Menu」を選択します。<br/>
+
DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2);
[[ファイル:archlinux-install-102.png | 400px]]
+
</syntaxhighlight>
  
 +
=== コードファイル(*.cpp) ===
 +
<syntaxhighlight lang="cpp">
 +
#define DLLAPI
  
「Secure Boot Menu」画面で「Secure Boot」が「Disabled」になっていることを確認します。<br/>
+
#include "CppDll.h"
「Disabled」になっていない場合は、「Disabled」に変更します<br/>
 
(画面見づらくてスミマセン…)<br/>
 
[[ファイル:archlinux-install-103.png | 400px]]
 
  
 +
DLLAPI long __stdcall _Sum(const long p_Number1, const long p_Number2)
 +
{
 +
return p_Number1 + p_Number2;
 +
}
 +
</syntaxhighlight>
  
== ファーストブートの無効化とブートデバイスの順番 ==
+
=== モジュール定義ファイル(*.def) ===
ファーストブートとブートデバイスの設定を確認します。<br/>
+
<syntaxhighlight lang="text">
画面上部のメニューから「Boot」を選択します。<br/>
+
LIBRARY CppDll
「Boot」画面中程の「Fast Boot」が「Disabled」になっていることを確認します。<br/>
 
「Disabled」になっていない場合は、「Disabled」に変更します<br/>
 
  
次に「起動順」の確認です。<br/>
+
EXPORTS
「Boot」画面下部の「Boot Option Priorities」の順番で、「Boot Option #1」にUSBメモリーが来るように設定します。<br/>
+
_Sum
(画面はUSBを刺さずに取ったので、USBメモリが表示されていません…スミマセン)<br/>
+
</syntaxhighlight>
[[ファイル:archlinux-install-104.png | 400px]]
 
  
 +
== C♯のプロジェクト作成 ==
 +
ほとんどそのまま作るんだけど…ソリューションのコンパイル対策をしておくよ。
  
== 保存して起動 ==
+
=== ビルドイベントの設定 ===
最後に「F4」キーを押して、保存してメニューを終了させます。
+
C++のDLLはソリューションフォルダ直下の「Debug」や「Release」フォルダにDLLが格納されてしまうんだ。そうすると、デバッグするときにDLLが見つからないので、ビルドイベントを使ってコピーしてしまうよ。以下のように設定してね。(「Release」コンパイルするまでは「Release」フォルダがないのでコメントアウトしているよ)<br/>
 +
[[ファイル:CShapeToCppDll-004.jpg]]<br/>
  
 +
=== プロジェクトの依存関係の設定 ===
 +
コピーするにもちゃんとリコンパイルされた資源をコピーしないといけないので、プロジェクトの依存関係を設定することで、ビルドの順番を設定するよ。<Br/>
 +
ソリューションエクスプローラーからC♯のプロジェクトを右クリックして「ビルド依存関係」→「プロジェクト依存関係」を選択してね。<br/>
 +
「依存関係」タブの依存先にC++のプロジェクトが表示されているはずだから、チェックを入れてOKボタンをクリックしてね。
  
= USBから起動 =
+
== C♯のコード ==
UEFIのメニューを終了すると、起動が始まります。<br/>
+
MVVMモデルでサンプルを作ったからビューモデルが入っているけど…DLLを呼ぶには必要ないから無視してね。
起動すると、以下の画面が表示されます。<br/>
+
=== モデル ===
この画面で「Arch Linux archiso x86_64 UEFI USB」を選択します。<br/>
+
<syntaxhighlight lang="C#">
[[ファイル:archlinux-install-004.png | 400px]]
+
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;
  
しばらく真っ黒な画面が続きますが、根気よく待ち続けます…。<br/>
+
//追加
しばらくすると、以下の画面が表示されます。<br/>
+
using System.Runtime.InteropServices;
[[ファイル:archlinux-install-005.png | 400px]]
 
  
この状態はいわゆる「ライブ起動(インストール無しで起動)」の状態です。<br/>
+
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>
== キーボード設定 ==
+
        /// 標準のコンストラクタ
今の状態は「英字キーボード」になっています。<br/>
+
        /// </summary>
英字キーボードを使用している人はそのままでも良いですが、日本語キーボードを使用してい人は記号の入力で手間取るので、日本語キーボードに切り替えます。<br/>
+
        public MainWindow()
以下のコマンドで選択できるキーボードの一覧を表示することが出来ます…(一覧見たからなんなんだって感じですが…)。
+
        {
<syntaxhighlight lang="bash">ls /usr/share/kbd/keymaps/**/*.map.gz</syntaxhighlight>
+
            InitializeComponent();
 +
        }
  
キーボードのロードは以下のコマンドを実行します。
+
        /// <summary>
<syntaxhighlight lang="bash">loadkeys jp106</syntaxhighlight>
+
        /// ボタンクリックイベントハンドラ
 +
        /// </summary>
 +
        /// <param name="sender">イベント送信元</param>
 +
        /// <param name="e">イベント情報</param>
 +
        private void Button_Click(object sender, RoutedEventArgs e)
 +
        {
 +
            //DLLの関数を呼び出す
 +
            Int32 l_Result = _Sum(300, 500);
  
== UEFIかどうか確認 ==
+
            //計算結果の表示
LattapnadaはネイティブUEFIなのでこの作業は不要です…。
+
            MessageBox.Show("計算結果:" + l_Result.ToString());
<syntaxhighlight lang="bash">ls /sys/firmware/efi/efivars</syntaxhighlight>
+
        }
このコマンドでnot foundにならなければ「UEFI」で起動されています。
+
    }
 +
}
 +
</syntaxhighlight>
  
== パーティション作成 ==
+
=== ビュー ===
以下の手順はまっさらなHDDにインストールする手順になっちゃってます。<br/>
+
<source lang="xml">
パーティションが作成済みの場合は、パーティションを削除してから作業してください。<br/>
+
<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;
  
まず、以下のコマンドでデバイス名を確認します。<br/>
+
//追加
<syntaxhighlight lang="bash">fdisk -l</syntaxhighlight>
+
using System.ComponentModel;
  
 +
namespace CSharpToCDLL
 +
{
 +
    class MainWindowViewModel : INotifyPropertyChanged
 +
    {
 +
        /// <summary>
 +
        /// ラベル表示用変数
 +
        /// </summary>
 +
        private String m_Label_Content;
  
こんな感じで、表示されます。(ちょっと表示が違うかもです…)
+
        /// <summary>
<syntaxhighlight lang="text">ディスク /dev/mmcblk0: 64 GiB, 68719476736 バイト, 134217728 セクタ
+
        /// ラベル表示文字列
ディスク型式: HARDDISK       
+
        /// </summary>
単位: セクタ (1 * 512 = 512 バイト)
+
        public String Label_Content
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
+
        {
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト</syntaxhighlight>
+
            set
大概「/dev/mmcblk0」になっているかと思います。<br/>
+
            {
 +
                this.m_Label_Content = value;
 +
                this.OnPropertyChanged("Label_Content");
 +
            }
 +
            get { return this.m_Label_Content; }
 +
        }
  
 +
        /// <summary>
 +
        /// プロパティ変更イベントハンドラ
 +
        /// </summary>
 +
        public event PropertyChangedEventHandler PropertyChanged;
  
以下のコマンドで「/dev/mmcblk0」にパーティションを作成していきます。<br/>
+
        /// <summary>
<syntaxhighlight lang="bash">fdisk /dev/mmcblk0</syntaxhighlight>
+
        /// プロパティ変更通知
 +
        /// </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♯]]
「fdisk」コマンドは対話型で起動します。<br/>
+
[[Category:C++]]
操作の一覧は「m」で見ることが出来ます。<br/>
+
[[Category:dll]]
<syntaxhighlight lang="text">Command (m for help): m
 
 
 
Help:
 
 
 
  DOS (MBR)
 
  a  toggle a bootable flag
 
  b  edit nested BSD disklabel
 
  c  toggle the dos compatibility flag
 
 
 
  Generic
 
  d  delete a partition
 
  F  list free unpartitioned space
 
  l  list known partition types
 
  n  add a new partition
 
  p  print the partition table
 
  t  change a partition type
 
  v  verify the partition table
 
  i  print information about a partition
 
 
 
  Misc
 
  m  print this menu
 
  u  change display/entry units
 
  x  extra functionality (experts only)
 
 
 
  Script
 
  I  load disk layout from sfdisk script file
 
  O  dump disk layout to sfdisk script file
 
 
 
  Save & Exit
 
  w  write table to disk and exit
 
  q  quit without saving changes
 
 
 
  Create a new label
 
  g  create a new empty GPT partition table
 
  G  create a new empty SGI (IRIX) partition table
 
  o  create a new empty DOS partition table
 
  s  create a new empty Sun partition table</syntaxhighlight>
 
 
 
 
 
 
 
今後主流になる可能性が高いGPTでパーティションテーブルを作成します。<br/>
 
GPTでパーティションテーブルを作成する場合は「g」を入力します。<br/>
 
<syntaxhighlight lang="text">Command (m for help): g
 
 
 
Created a new GPT disklabel (GUID: 2FA51CB3-DEF4-6645-9B9B-26EA9C143903).</syntaxhighlight>
 
 
 
 
 
次にパーティションを作成していきます。<br/>
 
Windowsの場合はこだわりが無い限り、パーティション分割はしないものですが…<br/>
 
Linuxでは普通にパーティション分割します。<br/>
 
 
 
以下のパーティション分割は、初心者向けになっています。<br/>
 
こだわりがある方は、自由に分割して良いかと思います。<br/>
 
 
 
今回は以下のパーティション作成します。
 
<dl>
 
<dt>/dev/mmcblk0p1</dt>
 
<dd>EFI用パーティション(512MByte)</dd>
 
<dt>/dev/mmcblk0p2</dt>
 
<dd>システム用パーティション(64GByte - 512MByte - 4GByte)</dd>
 
<dt>/dev/mmcblk0p3</dt>
 
<dd>スワップ用パーティション(4GByte)</dd>
 
</dl>
 
 
 
まず、UEFI用のパーティションを512MByteで作成します。<br/>
 
パーティションの作成は「n」で行います。
 
<syntaxhighlight lang="text">Command (m for help): n
 
Partition number (1-128, default 1):
 
First sector (2048-134217694, default 2048):
 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-134217694, default 134217694): +512M
 
 
 
Created a new partition 2 of type 'Linux filesystem' and of size 512 MiB.</syntaxhighlight>
 
 
 
次に、システム用パーティションを「残りの容量 - 4GByte」で作成します。
 
<syntaxhighlight lang="text">Command (m for help): n
 
Partition number (1,3-128, default 2):
 
First sector (1050624-134217694, default 1050624):
 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1050624-134217694, default 134217694): -4G
 
 
 
Created a new partition 1 of type 'Linux filesystem' and of size 59.5 GiB.</syntaxhighlight>
 
 
 
最後に、スワップ用パーティションを4GByteで作成します。
 
<syntaxhighlight lang="text">Command (m for help): n
 
Partition number (3-128, default 3):
 
First sector (125829120-134217694, default 125829120):
 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (125829120-134217694, default 134217694):
 
 
 
Created a new partition 3 of type 'Linux filesystem' and of size 4 GiB.</syntaxhighlight>
 
 
 
それぞれの目的に合わせてパーティションタイプを設定します。<br/>
 
設定できるパーティションタイプは「l」で確認することが出来ます。<br/>
 
リストから抜ける場合は「q」を押します。<br/>
 
 
 
 
 
「/dev/mmcblk0p1」はUEFI用パーティションなので、「EFI System」を設定します。<br/>
 
パーティションタイプの設定は「t」で行います。
 
<syntaxhighlight lang="text">Command (m for help): t
 
Partition number (1-3, default 3): 1
 
Partition type (type L to list all types): 1
 
 
 
Changed type of partition 'Linux filesystem' to 'EFI System'.</syntaxhighlight>
 
 
 
「/dev/mmcblk0p3」はスワップ用パーティションなので、「Linux swap」を設定します。
 
<syntaxhighlight lang="text">Command (m for help): t
 
Partition number (1-3, default 3): 3
 
Partition type (type L to list all types): 19
 
 
 
Changed type of partition 'Linux filesystem' to 'Linux swap'.</syntaxhighlight>
 
 
 
「/dev/mmcblk0p2」を設定していませんが、デフォルトで「Linux File System」なので特に変更しません。
 
 
 
最後に、これまで設定した内容をHDDに書き込みます。<br/>
 
HDDへの書き込みは「w」で行います。
 
<syntaxhighlight lang="text">Command (m for help): w
 
The partition table has been altered.
 
Calling ioctl() to re-read partition table.
 
Syncing disks.</syntaxhighlight>
 
 
 
== フォーマット ==
 
各パーティションを利用できるようにするために、フォーマットしていきます。<br/>
 
使用目的によって、フォーマットのやり方が異なります。
 
 
 
UEFI領域のフォーマットは、以下のコマンドで、FAT32にフォーマットします。
 
<syntaxhighlight lang="bash">mkfs.fat -F32 /dev/mmcblk0p1</syntaxhighlight>
 
 
 
システム領域は以下のコマンドで、ext4にフォーマットします。
 
<syntaxhighlight lang="bash">mkfs.ext4 /dev/mmcblk0p2</syntaxhighlight>
 
 
 
スワップ領域は以下のコマンドで、swap領域に設定します。
 
<syntaxhighlight lang="bash">mkswap /dev/mmcblk0p3
 
swapon /dev/mmcblk0p3</syntaxhighlight>
 
 
 
== マウント ==
 
フォーマットが終わったら、HDDをマウントします。<br/>
 
ここはAcrhLinuxのインストールガイドに則り、以下のコマンドで「/mnt」にマウントします。
 
<syntaxhighlight lang="bash">mount /dev/mmcblk0p2 /mnt</syntaxhighlight>
 
 
 
UEFI領域は「/mnt/boot」にマウントします。
 
<syntaxhighlight lang="bash">mkdir /mnt/boot
 
mount /dev/mmcblk0p1 /mnt/boot</syntaxhighlight>
 
 
 
== システムクロックの設定 ==
 
よくわからないのですが…www<br/>
 
システムクロックの設定をします。<br/>
 
(ntpを使用するように設定しているのかな?)
 
<syntaxhighlight lang="bash">timedatectl set-ntp true</syntaxhighlight>
 
 
 
 
 
== ミラーサイトの設定 ==
 
「/etc/pacman.d/mirrorlist」を編集して、ミラーサイトを設定します。<br/>
 
どうやらデフォルトで「nano」が入っているようなので、nanoで編集します<br/>
 
<syntaxhighlight lang="bash">nano /etc/pacman.d/mirrorlist</syntaxhighlight>
 
 
 
すごい量が表示されるかと思います。<br/>
 
日本のミラーサイトは3つ登録されていますので、それを最上位(ファイルの先頭)に移動します。<br/>
 
 
 
 
 
== プロキシが必要なら設定 ==
 
プロキシ配下でインストールしている場合は、ここでプロキシの設定をしておきます。<br/>
 
以下のコマンドで、プロキシの環境変数を設定します。<br/>
 
<syntaxhighlight lang="bash">export HTTP_PROXY=[userid]:[password]@[host]:[port]
 
export HTTPS_PROXY=[userid]:[password]@[host]:[port]
 
export http_proxy=[userid]:[password]@[host]:[port]
 
export https_proxy=[userid]:[password]@[host]:[port]</syntaxhighlight>
 
[userid][password][host][port]はそれぞれ、実際の値に置き換えてください。<br/>
 
パスワードやユーザーIDに「@」が含まれる場合は「%40」に置き換えます。<br/>
 
(その他記号も置き換える必要があります。詳しくはググってください)
 
 
 
== ベースシステムのインストール ==
 
ようやくインストールです。<br/>
 
以下のコマンドを実行して、HDDにArchLinuxをインストールしてください。
 
<syntaxhighlight lang="bash">pacstrap /mnt base base-devel</syntaxhighlight>
 
 
 
= システム設定 =
 
== fstabの作成 ==
 
以下のコマンドを実行して、システム起動時のパーティションマウントを設定します。
 
<syntaxhighlight lang="bash">genfstab -U /mnt >> /mnt/etc/fstab</syntaxhighlight>
 
この作業で、再起動後「/dev/mmcblk0p2」がルートディレクトリになります。
 
 
 
== 一時的にルートディレクトリを変更 ==
 
この後の設定のために、ルートディレクトリを変更します。
 
<syntaxhighlight lang="bash">arch-chroot /mnt</syntaxhighlight>
 
 
 
== タイムゾーンの設定 ==
 
以下のコマンドを実行して、タイムゾーンを設定します。
 
<syntaxhighlight lang="bash">ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
 
hwclock --systohc --utc</syntaxhighlight>
 
 
 
== ロケールの設定 ==
 
「/etc/locale.gen」を編集して、利用するロケールを選択します。<br/>
 
「nano」で「/etc/locale.gen」を開いて、「en_US.UTF-8 UTF-8」と「ja_JP.UTF-8 UTF-8」をコメントアウトします。
 
<syntaxhighlight lang="bash">nano /etc/locale.gen</syntaxhighlight>
 
 
 
編集後、以下のコマンドを実行して、ロケール等を反映します。
 
<syntaxhighlight lang="bash">locale-gen
 
echo LANG=en_US.UTF-8 > /etc/locale.conf
 
echo KEYMAP=jp106 > /etc/vconsole.conf</syntaxhighlight>
 
 
 
== ホストネームの設定 ==
 
以下のコマンドを実行して、ホストネームを設定します。
 
<syntaxhighlight lang="bash">echo [hostname] > /etc/hostname</syntaxhighlight>
 
[hostname]は実際に合わせて置き換えてください。
 
 
 
また、以下の様に「hosts」ファイルを編集します。
 
<syntaxhighlight lang="bash">nano /etc/hosts</syntaxhighlight>
 
 
 
内容は以下のとおりです。
 
<syntaxhighlight lang="text">127.0.0.1 localhost
 
::1 localhost
 
127.0.1.1 [hostname].localdomain [hostname]</syntaxhighlight>
 
 
 
== rootパスワードの変更 ==
 
rootアカウントのパスワードを変更します。
 
<syntaxhighlight lang="bash">passwd</syntaxhighlight>
 
 
 
 
 
== マイクロコードのインストール ==
 
LattepandはIntelのCPUを使用しているので、以下のコマンドを実行してマイクロコードをインストールします。<br/>
 
<syntaxhighlight lang="bash">pacman -S intel-ucode</syntaxhighlight>
 
 
 
== GRUBのインストール ==
 
以下のコマンドを実行して、GRUBブートローダーとEFIブートマネージャーをインストールします。
 
<syntaxhighlight lang="bash">pacman -S grub
 
pacman -S efibootmgr</syntaxhighlight>
 
 
 
また、以下のコマンドでArchLinuxをGRUBに登録します。
 
<syntaxhighlight lang="bash">grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=boot</syntaxhighlight>
 
(bootlorder-idをbootに修正しました)
 
 
 
以下のコマンドを実行して、GRUBの設定ファイルを生成します。
 
<syntaxhighlight lang="bash">grub-mkconfig -o /boot/grub/grub.cfg</syntaxhighlight>
 
 
 
今の状態で再起動すると、UEFIのシェルからファイルを選択する羽目になります。<br/>
 
自動でGRUBが起動するように、以下のコマンドを実行してefiファイル名を変更します。
 
<syntaxhighlight lang="bash">mv /boot/EFI/boot/grubx64.efi /boot/EFI/boot/bootx64,efi</syntaxhighlight>
 
 
 
== chrootから抜ける ==
 
chroot内の作業が終わりましたので、以下のコマンドで抜けます。
 
<syntaxhighlight lang="bash">exit</syntaxhighlight>
 
 
 
== アンマウント ==
 
「fstab」に設定済みなので、再起動後は「/mnt」のマウントが不要になります。<br/>
 
なので、「/mnt」を、以下のコマンドでアンマウントします。<br/>
 
(と言っても、再起動した時点でアンマウントされるのですが…)
 
<syntaxhighlight lang="bash">umount -R /mnt</syntaxhighlight>
 
 
 
== 再起動 ==
 
USBメモリを外したいので、再起動と言いつつ以下のコマンドでシャットダウンします。
 
<syntaxhighlight lang="bash">shutdown -h now</syntaxhighlight>
 
 
 
== USBメモリの取り外しと起動 ==
 
シャットダウンしたら、USBの取り外します。<br/>
 
電源ボタンを押して、Lattepandaを起動します。
 
 
 
== ログイン ==
 
ログイン画面が表示されたらログインします。<br/>
 
ユーザーIDは「root」で、パスワードはインストールで設定したパスワードです。
 
 
 
== ネットワークの有効化 ==
 
デフォルトではネットワークが自動で起動しないようになっています。<br/>
 
ネットワークを自動で有効になるように設定します。<br/>
 
 
 
先ずは以下のコマンドを実行してNICのデバイス名を取得します。
 
<syntaxhighlight lang="bash">ip a</syntaxhighlight>
 
 
 
こんなふうに表示されるかと思います。
 
<syntaxhighlight lang="text">1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 
    inet 127.0.0.1/8 scope host lo
 
      valid_lft forever preferred_lft forever
 
    inet6 ::1/128 scope host
 
      valid_lft forever preferred_lft forever
 
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
 
    link/ether 08:00:00:00:00:00brd ff:ff:ff:ff:ff:ff
 
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute enp0s3
 
      valid_lft 82004sec preferred_lft 82004sec
 
    inet6 fe80:0000:0000:0000:0000:0000/64 scope link noprefixroute
 
      valid_lft forever preferred_lft forever</syntaxhighlight>
 
「lo」じゃないほうがデバイス名です(この場合「enp0s3」です)。
 
 
 
NICのデバイス名を取得したら、以下のコマンドを実行します。
 
<syntaxhighlight lang="bash">systemctl enable dhcpcd@[interface].service</syntaxhighlight>
 
[interface]をNICのデバイス名に置き換えてください。
 
 
 
= 参考サイト =
 
[https://wiki.archlinux.jp/index.php/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%82%AC%E3%82%A4%E3%83%89 インストールガイド - ArchWiki]<br/>
 
[https://qiita.com/Gen_Arch/items/da296b7cbe5d87abc5a4 ArchLinuxのインストール(3つのブート方式ごとの設定) - Qiita]<br/>
 
[https://wiki.archlinux.jp/index.php/%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8B%E3%83%B3%E3%82%B0 パーティショニング - ArchWiki]<br/>
 
[https://qiita.com/honeniq/items/579b36588f3c1061edf5 Arch LinuxをVirtualBox上にインストール - Qiita]<br/>
 
[https://mattintosh.hatenablog.com/entry/20180308/1520518082 VirtualBox の UEFI で Ubuntu が起動しない - mattintosh note]<br/>
 
 
 
[[Category:ArchLinux]]
 
[[Category:Lattepanda]]
 

2019年7月26日 (金) 16: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));
            }
        }
    }
}