C#でポインタを実際に使用していますか?[閉まっている]


19

ポインターを使用することが良いまたは必要なオプションであるC#でコーディングしているときの状況は何ですか?安全でないポインターについて話している。


8
ああ、C#では常にポインターを使用しているが、安全でないキーワードを明示的に言うことでそれを台無しにしなければならないと説明できるので、質問を見て喜んでいます。やった!:)
トニー

回答:


25

C#の開発者自身から:

ポインターの使用がC#で必要になることはほとんどありませんが、ポインターを必要とする状況がいくつかあります。例として、安全でないコンテキストを使用してポインターを許可することは、次の場合に保証されます。

  • ディスク上の既存の構造を扱う
  • ポインターを含む構造を含む高度なCOMまたはプラットフォーム呼び出しシナリオ
  • パフォーマンスが重要なコード

他の状況での安全でないコンテキストの使用は推奨されません。

具体的には、C#でCコードを記述しようとするために、安全でないコンテキストを使用しないでください。

注意: 「安全でないコンテキストを使用して記述されたコードは安全であると確認できないため、コードが完全に信頼されている場合にのみ実行されます。インターネットから直接コード。」

あなたはこれを参考にしてください


「信頼できない環境では、安全でないコードは実行できません。」「信頼できる」という意味ですか?
ドンラリンクス

18

はい、パフォーマンスが重要で操作が低レベルの場合、実際の用途があります

たとえば、画像比較のためにC#で1回だけポインターを使用する必要がありました。1024x1024x32の画像のペアでGetPixelを使用すると、比較に2分かかりました(完全一致)。画像メモリを固定し、ポインタを使用するのに1秒もかかりませんでした(もちろん同じマシン上で)。


2
私は...あなたがそのためにするLockBitsを使用していた(msdn.microsoft.com/en-us/library/...
コンフィギュレータ

1
@configurator:これは.net 2で、LockBitsは存在しませんでした
スティーブンA.ロウ

2
確かにそれは、それは... 1.0から存在しなかった
コンフィギュレータ

@configurator:私のエラー、MSDNドキュメントのナビゲートが混乱しました(ドロップリストで.net 2に変更すると、lockbitsに言及していないまったく別のページに移動しました)。はい、それが画像メモリの固定方法です。
スティーブンA.ロウ

6

Microsoftのデザイナーは賢い人であり、C#に追加するものにはすべて少なくとも1つのユースケースがあることを覚えておく必要があります。FParsecプロジェクトは、 C#が可能であることが、パフォーマンスの最後の一滴を引き出すために、安全でないコードを使用しています。使用の通知を取るfixedstackalloc

private char* ReadCharsFromStream(char* buffer, int maxCount, out string overhangChars) {
    Debug.Assert(maxCount >= 0);
    fixed (byte* byteBuffer = ByteBuffer) {
        overhangChars = null;
        try {
            while (maxCount >= MaxCharCountForOneByte) {// if maxCount < MaxCharCountForOneByte, Convert could throw
                int nBytesInByteBuffer = FillByteBuffer();
                bool flush = nBytesInByteBuffer == 0;
                int bytesUsed, charsUsed; bool completed = false;
                Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
                                buffer, maxCount, flush,
                                out bytesUsed, out charsUsed, out completed);
                ByteBufferIndex += bytesUsed; // GetChars consumed bytesUsed bytes from the byte buffer
                buffer += charsUsed;
                maxCount -= charsUsed;
                if (flush && completed) return buffer;
            }
            if (maxCount == 0) return buffer;

            char* cs = stackalloc char[MaxCharCountForOneByte];
            for (;;) {
                int nBytesInByteBuffer = FillByteBuffer();
                bool flush = nBytesInByteBuffer == 0;
                int bytesUsed, charsUsed; bool completed;
                Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
                                cs, MaxCharCountForOneByte, flush,
                                out bytesUsed, out charsUsed, out completed);
                ByteBufferIndex += bytesUsed;
                if (charsUsed > 0) {
                    int i = 0;
                    do {
                        *(buffer++) = cs[i++];
                        if (--maxCount == 0) {
                            if (i < charsUsed) overhangChars = new string(cs, i, charsUsed - i);
                            return buffer;
                        }
                    } while (i < charsUsed);
                }
                if (flush && completed) return buffer;
            }
        } catch (DecoderFallbackException e) {
            e.Data.Add("Stream.Position", ByteIndex + e.Index);
            throw;
        }
    }
}

1
開発者(Microsoftまたは他の会社)は、ユースケースが1つであるため、何らかの機能が含まれているとばかだと思います。機能には1つ以上のユースケースが必要です。それ以外の場合は、肥大化しています。
ライライアン

4
Raymond Chenは、Microsoftの機能は-100の「ポイント」から始まるとよく言っています。機能を実装するには、「パッケージ全体に大きなプラスの効果をもたらす必要があります」。このc.2004についてここでのericguのブログ記事:blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx
ジェシー・ブキャナン

一部の文字列操作では、安全でないコードが内部的に使用されていると確信しています。そのため、FParsecが優先事項ではなかったかもしれません。
アルトゥーロトーレスサンチェス

4

かつて、ヘッドセットへのインターフェイスとして機能するC#ベースのWindowsアプリケーションで(安全でないコンテキストで)ポインターを使用する必要がありました。このアプリケーションは、エージェント(コールセンター)がヘッドフォン設定を制御できるようにするユーザーインターフェイスです。このアプリケーションは、ヘッドセットメーカーが提供するコントロールパネルの代替として機能します。したがって、ヘッドセットを制御する機能は、利用可能なオプションと比較すると制限されていました。P / Invokeを使用してヘッドセットメーカーが提供するAPI(Visual C ++ dll)を使用する必要があるため、ポインターを使用する必要がありました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.