こんにちは、Takymです。
今回だけ自分の名前の色を変えてみました。次回からは直します。
実は、拡張子とプロトコルの登録のプログラムの実験をしていたのですが、失敗してしまいブログ記事にする事ができませんでした。
なので今回は“今日はC#インタラクティブ”の記事にしたいと思います。
CSI.EXEでポインタを使う編
Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.
C:\Windows\System32>csi.exe
Microsoft (R) Visual C# インタラクティブ コンパイラ バージョン 1.3.1.60616
Copyright (C) Microsoft Corporation. All rights reserved.
詳細については、「#help」と入力します。
> int *a = 0x12345678;
(1,1): error CS0214: ポインターおよび固定サイズ バッファーは、unsafe コンテキストでのみ使用することができます。
(1,10): error CS0266: 型 'int' を 'int*' に暗黙的に変換できません。明示的な変換が存在します (cast が不足していないかどうかを確認してください)
// ↑まぁそうなるよな・・・
> int a = 0x9ABCDEF0;
(1,9): error CS0266: 型 'uint' を 'int' に暗黙的に変換できません。明示的な変換が存在します (cast が不足していないかどうかを確認してください)
// ↑なんでこんな間違e(殴
> int a = 1234;
> unsafe int *b = &a;
(1,17): error CS0212: fixed ステートメントの初期化子内の fixed でない式のアドレスのみを取得できます。
// ↑ああ、やっぱりunsafeの後に直接文を書くことはできないのか。 (・_・D フムフム・・・
> unsafe {
. int *b = &a;
. int c = *b;
. WriteLine(c); // C#インタラクティブではConsoleを省略する事ができる。
. }
(2,10): error CS0212: fixed ステートメントの初期化子内の fixed でない式のアドレスのみを取得できます。
// むぅ!?なんだこれは!?
> unsafe {
. fixed (int *b = &a) {
. int* c = b; // C#では「int *p」ではなく「int* p」だという事をこの段階で気づいた。
. WriteLine("C-addr" + c);
. WriteLine("C-valu" + *c);
. }
. }
(4,11): error CS0019: 演算子 '+' を 'string' と 'int*' 型のオペランドに適用することはできません
// あ、変換忘れた☆テヘ
// あと、WriteLineで出力する内容の書式も変だな・・・
> unsafe {
. fixed (int* b = &a) {
. WriteLine($"address:{new IntPtr(c)}"); // 今度は普通の表記にしてみた。
. WriteLine($"value:{*c}");
. }}
(3,33): error CS0103: 現在のコンテキストに 'c' という名前は存在しません。
(4,21): error CS0103: 現在のコンテキストに 'c' という名前は存在しません。
// ↑う~ん、僕はどうしてこんな間違えをするんだろう・・・
C:\Windows\System32>csi.exe
Microsoft (R) Visual C# インタラクティブ コンパイラ バージョン 1.3.1.60616
Copyright (C) Microsoft Corporation. All rights reserved.
詳細については、「#help」と入力します。
> int a = 1234;
// ↑間違えてCtrl+Cを押しちゃったけど復元復元...
> unsafe fixed (int *b = &a) {
. WriteLine($"address:{new IntPtr(c)}");
(1,14): error CS1031: 型が必要です。
(1,14): error CS1001: 識別子がありません
(1,14): error CS1528: ; または = を指定してください (宣言の中にコンストラクター引数は指定できません)
(1,14): error CS1003: 構文エラーです。'[' が必要です。
(1,15): error CS1525: 'int' は無効です。
+
さらに 3 件のエラー
// ↑ん?何だ?「}」を入れてないのに?バグかな?
// 間違えてEnterキーを押してしまったとかかな?
// 試してみよう。
> {
.
.
.
.
. }
// う~ん... 色んな方法でEnterキーを押してみたけど、何も起こらないぞ???
> unsafe fixed (int* b = &a) {
. WriteLine($"address:{new IntPtr(c)}");
(1,14): error CS1031: 型が必要です。
(1,14): error CS1001: 識別子がありません
(1,14): error CS1528: ; または = を指定してください (宣言の中にコンストラクター引数は指定できません)
(1,14): error CS1003: 構文エラーです。'[' が必要です。
(1,15): error CS1525: 'int' は無効です。
+ さらに 3 件のエラー
// あ、やっぱり。「unsafe fixed」とか「$"address:{new IntPtr(c)}"」とかが悪いのかも。
// 普通の書き方をしよう。
> unsafe {
. fixed (int* b = &a) {
. IntPtr p = new IntPtr(b);
. WriteLine(&"address:{p}");
. }
. }
(4,12): error CS0211: 式のアドレスを取得できません。
// ああああ!打ち間違いしたぁぁぁ!
// なんか調子が悪いなぁ。今日は。
// 最近C#インタラクティブ弄っていなかったからかな???
> int a = 1234;
> unsafe {
. fixed (int* b = &a) {
. IntPtr p = new IntPtr(b);
. WriteLine($"address:{p}");
. WriteLine($"value:{*b}");
. }}
address:2424761936080
value:1234
// ↑ふぅ~ やっと成功したぁ~。
> unsafe fixed (int* b = &a) {
. IntPtr p = new IntPtr(b);
(1,14): error CS1031: 型が必要です。
(1,14): error CS1001: 識別子がありません
(1,14): error CS1528: ; または = を指定してください (宣言の中にコンストラクター引数は指定できません)
(1,14): error CS1003: 構文エラーです。'[' が必要です。
(1,15): error CS1525: 'int' は無効です。
+ さらに 4 件のエラー
> WriteLine($"address:{p}");
(1,22): error CS0103: 現在のコンテキストに 'p' という名前は存在しません。
> WriteLine($"value:{*b}");
(1,21): error CS0103: 現在のコンテキストに 'b' という名前は存在しません。
> }
// ↑ああ。やっぱり、「unsafe fixed」はダメなのか。
// じゃあ、「$"address:{new IntPtr(c)}"」は?
> $"{new object()}"
"System.Object"
// ↑まずは、objectクラスで試してみたけど成功した。
// 肝心な「$"address:{new IntPtr(c)}"」は?
> unsafe{
. int a = 5678;
. fixed (int* b = &a) {
. WriteLine($"{new IntPtr(b)}");
. }
. }
(3,17): error CS0213: 既に fixed が使用されている式のアドレスを取得するために、fixed ステートメントを使用することはできません。
// ↑ようわからん...
// もう一度、
> unsafe {
. int a = 4321;
. int* b = &a;
. WriteLine($"{new IntPtr(b)}");
. }
1725270533972
// ↑うん、普通に成功した。
// 「unsafe fixed」が一番悪かったのか(・_・D フムフム
感想
なんか今回はダラダラしていてすみません。
感想・意見・誤字・脱字等はこの記事のコメント欄にお願いします。
最後まで読んでくださってありがとうございました。