問題タブ [void-pointers]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - void ポインター: C と C++ の違い
void ポインターに関する C と C++ の違いを理解しようとしています。以下は C でコンパイルされますが、C++ ではコンパイルされません (すべてのコンパイルは gcc/g++ -ansi -pedantic -Wall で行われます)。
malloc
を返すためvoid*
、C++ では代入が許可されていませんが、int*
C では許可されています。
ただし、ここでは:
C++ と C の両方で問題なくコンパイルできます。なんで?
K&R2 言う:
オブジェクトへのポインタは
void *
、情報を失うことなく型に変換できます。結果が元のポインター型に変換されると、元のポインターが復元されます。
そして、これvoid*
は C での変換に関するすべてを要約したものです。C++ 標準は何を規定していますか?
c - CでVoidタイプのパラメーターを渡す
こんにちは、私はCで割り当てに取り組んでおり、未知のタイプのパラメーターを関数に渡す必要があります。
たとえば、次のようなものがあるとします。
可変要素が無効である理由は、3種類の可能性があるためです。ただし、3つすべてに「Count」という名前のメンバー変数があります。
Eclipeseで記述した実際のコードをコンパイルしようとすると、次のエラーが発生します。
エラー:構造体または共用体ではないもののメンバー'Count'の要求
コンパイラが「要素」のタイプを事前に知らないため、これが起こっていると思います。しかし、なぜこれが機能しないのかわかりません。
手伝ってくれてありがとう!
c++ - reinterpret_cast を使用する代わりに void* を介してキャストする
私は本を読んでreinterpret_cast
いますが、直接使用するべきではなく、 void* と組み合わせてキャストする必要があることがわかりましたstatic_cast
:
それ以外の:
ただし、これが直接キャストよりも優れている理由の説明が見つかりません。誰かが私に説明をしてくれたり、答えを教えてくれたりすると、とても感謝しています。
前もって感謝します
ps何にreinterpret_cast
使われるかは知っていますが、このように使われているのを見たことがありません
c - void のサイズが不明な場合のポインター演算
Visual Studio C++ バージョン 9 (およびおそらく他のバージョンも) では、次のコード:
このコードは GCC で動作しsizeof(void)
、1
.
char *
ポインター演算の目的で明示的にキャストすると混乱が生じるため、この制限を回避する方法はありますか(void *
生メモリへの型なしポインターとしてよく認識され、使用されます)。
Update0
- 注意してください、私は標準の存在をよく知っています。
- 生のポインタ演算を行いたい。
- それが問題の原因で
sizeof(void)
はないという事実を十分に認識していることを示します。1
- コード例は、エラーを生成するために何が必要かを示すためのものです。
- これが を使用する「通常の」方法ではないことはわかっています
void
が、これは C であり、これらのことが起こります。 - はい、人々はこれを低レベルで行う必要があります。私は理由を求めているのではなく、方法を求めています。理由を知りたい場合は、カーネル ソースまたは使いやすい glibc を参照してください。
アップデート1
この質問は多くの混乱を引き起こしたようです。問題は、なぜ持つことが標準的でないのかということsizeof(void) == 1
ではなく、標準的でない場合にどうするかということです。
1 バイトのポインター演算が行われる場合、 にキャストすることchar *
が正しい答えであることがわかります。*(void *)
これは、 サイズがないからではなく、標準が実際に*(char *)
は常にであると保証しているため1
です。したがって、 の使用は常に正しく、生のポインター演算の目的で GCC 拡張char *
と一致します。void *
ポイントをさらに強化するために、型のvoid *
ないメモリへのポインターの正しい選択であり、生のポインター演算のchar *
キャスト先の正しい型です。
c - sizeof(char) != 1 の場合の C でのバイト精度ポインタ演算
単一バイト精度でポインタ演算を移植可能に実行するにはどうすればよいですか?
それを念頭に置いて:
char
すべてのプラットフォームで 1 バイトではないsizeof(void) == 1
GCC の拡張機能としてのみ利用可能- 一部のプラットフォームではポインター deref ポインターのアラインメントに制限がある場合がありますが、算術演算には最小の基本 POD 型のサイズよりも細かい粒度が必要な場合があります。
python - *output* セマンティクスを持つ入力パラメーターを使用して、 C から呼び出し可能な python 関数を構築する
ユースケースは次のとおりです。
- Cで実装された(固定された、変更不可能な)DLLが与えられた場合
- 求む: Python で実装されたこの DLL のラッパー (選択したメソッド: ctypes)
DLL の一部の関数には、同期プリミティブが必要です。最大限の柔軟性を目指して、DLL の設計者はクライアント提供のコールバックに完全に依存しています。より正確には、この DLL には以下が必要です。
- 同期オブジェクトを作成するためのコールバック関数
- 同期オブジェクトのロックを取得/解放するコールバック関数
- 同期オブジェクトを破棄する 1 つのコールバック関数
DLL の観点からは、同期オブジェクトは不透明であるため、void *
エンティティによって表現されます。たとえば、DLL 関数の 1 つがロックを取得したい場合は、次のようにします。
コールバックcreate_mutex
入力パラメータには出力セマンティクスがあることがわかります。これはvoid **
署名によって達成されます。
このコールバック (および他の 3 つ) は、Python で実装する必要があります。私は失敗しました :-) 簡単にするために、コールバックの作成のみに焦点を当てましょう。また、簡単にするために、不透明なオブジェクトをint
.
コールバックの使用をエミュレートする toy-DLL は次のとおりです (ct_test.c):
コールバックを提供し、DLL を使用する Python コードは次のとおりです。
DLL 内で提供されるコールバック ( 経由で設定set_c_callback()
) を使用する場合、これは期待どおりに機能します。
ただし、それ以外の場合 (Python コールバックを使用する場合) は失敗します。
どこが間違っていますか?
c - 汎用性と型安全性? C で void* を使用する
オブジェクト指向 (C#、Java、Scala) 出身の私は、コードの再利用と型安全性の両方の原則を非常に高く評価しています。上記の言語の型引数はその役割を果たし、型安全でコードを「無駄」にしない汎用データ構造を有効にします。
C に行き詰まるにつれて、妥協しなければならないことを認識しており、それが正しいものであってほしいと思っています。データ構造のvoid *
各ノード/要素に があり、型の安全性が失われるか、使用する型ごとに構造とコードを書き直す必要があります。
コードの複雑さは明らかな要因です。配列または連結リストを繰り返し処理することは簡単で*next
、構造体に a を追加することは余分な労力ではありません。このような場合、構造とコードを再利用しようとしないことは理にかなっています。しかし、より複雑な構造の場合、答えはそれほど明白ではありません。
モジュール性とテスト容易性もあります。構造を使用するコードから型とその操作を分離すると、テストが容易になります。逆もまた真です。他のことをしようとしている間に構造体に対するコードの反復をテストすると、面倒になります。
それで、あなたのアドバイスは何ですか?void *
再利用または型安全性と重複コードはありますか? 一般原則はありますか?適合しない場合、オブジェクト指向を手続き型に強制しようとしていますか?
編集: C++ をお勧めしないでください、私の質問は C についてです!
c++ - voidポインタバッファからの構造体のインスタンス化
これが私には面白そうなC++コードですが、動作することはわかっています。
構造体が定義されており、プログラムではvoidポインタを使用してメモリを割り当てます。次に、割り当てられたバッファを使用して構造体が作成されます。
ここにいくつかのコードがあります
コードにはもっと多くのものがありますが、それがその要点です。
私はこのコードをテストしていませんが、私が見ているコードは非常によくテストされており、機能します。しかし、どのように?
ありがとう。
編集:そのメモリリークを修正しました。
c - 整数値を void* にキャストすることは、コールバックでよく使用されるパラダイムですか?
値への実際のポインターを送信するのではなく、値をポインターにキャストします。これらの例は、GTK プログラムの GUI インターフェイス コードで見つかりました。
上記の例では、 の最後のパラメーターを参照していますg_signal_connect
。on_paste_button_pressed
GTK2 によって呼び出されると、次のように void ポインターをキャストし直しますon_paste_button_pressed
。user_data
実際には、この特定の例をコードに追加しましたが、既存のものに基づいています。キャストに関する警告を避けるために、ビットシフトを追加しました。プログラム自体には、多数のウィジェットを含む 4 つのペインがあり、コピーと貼り付けのボタンを使用して、あるペインから別のペインにすべての値をコピーできます。
値をポインタアドレスにキャストするこの方法はよく使用されますか?また、これを使用しない理由はありますか?
編集:
整数から void ポインターへのキャストも、次のように実行できます。
c++ - C++: void* へのキャストとその逆
* ---編集 - ソース全体*
最後にデバッグすると、「get」と「value」の値が違う!おそらく、間違った方法で void* に変換して User に戻しますか?
解決
すべてのPODをvoid *に変換し、これらの部分を結合する一種の「シリアライザ」を作成します
PS または、User を POD タイプに書き換えると、すべてがうまくいくと思います。
追加
それは奇妙ですが...私はdefenetly非podオブジェクトをvoid *にキャストして戻し(内部にstd::stringがあります)、それで問題ありません(dbに送信して戻す必要はありません)。どうしてですか?そして、'trough' db defenetly pod オブジェクトをキャストして送信した後 (追加のメソッドはありません。すべてのメンバーはポッドです。単純な構造体 {int a; int b; ...} です)。私のアプローチの何が問題になっていますか?
最初の「追加」の約 1 週間後に追加
くそー...私はそれをコンパイルしました。それが返す汚れの種類を見てください。大丈夫!・・・無理!... ああ!. 主よ... 合理的な質問 (状況の 99.999% で正しい答えは「私の」ですが... ここでは...) - これは誰のせいですか? 私またはVS?