0

質問をする前に、「類似した」質問がいくつかあることを理解していると言いたいのですが、私の質問に具体的に答えるものは何もありません (見つけることができる)。

以下が可能かどうか疑問に思っています。new次のように、クラスのインスタンスを作成するとします。

MyClass* classInstance = new MyClass();

生のメモリアドレスをintのようなプリミティブ型に保存できるかどうか疑問に思っています。次に、へのポインターがない C++ の無人地帯のどこかで、classInstance次のようなことができます。

MyClass* myClassInstanceSomewhereInMemory = (MyClass*)0x12345678;
myClassInstanceSomewhereInMemory->workPlzKThx(); //Yay, it works!

これが可能である場合、リスクはありますか? そのようなことのオーバーヘッドに大きなコストはありますか? 私はこのかなり貧弱な設計を理解していますが、残念ながら私はここで第三者に翻弄されています. だから、これで私を責めないでください。:)

この狂気の説明では、なぜ私がこのようなばかげたことをしなければならないのかを
もう少し詳しく説明します。box2D を AIR ネイティブ拡張に移植していますが、前述のように、AIR ランタイムに翻弄されています。ネイティブ側と Actionscript 側の間の関連付けを処理する方法は...めちゃくちゃで、さらに、この関連付けを行うためのばかげたルールがたくさんあります。

そのようなルールの 1 つは、(プライベート コンストラクターを持つ) 型b2World->createBody()へのポインターを返す のような状況で実際の問題を引き起こします。b2Bodyこの関連付け中に、コンテキストを同時に作成して新しいポインターを関連付けることはできません。b2Bodyこれは、この呼び出し中に のコンテキスト内で立ち往生しているためですb2Worldb2Worldしたがって、 andのようなクラス内で一連の汚いハックを一緒に平手打ちするのではなくb2Body、 int のようなプリミティブ型を使用して、 new のメモリアドレスを保存して返すことができるかどうか疑問に思っていますb2Body

C++ から型付けされたポインターまたは構造体を Actionscript 側に返すことができません。コンテキストに関連付けることしかできません...しかし、プリミティブ型を返すことはできます。

4

4 に答える 4

2

最も簡単な解決策は、std::map<unsigned int, MyClass*>. 唯一の欠点は、UINT_MAX割り当て後に再利用可能な値を探しに行かなければならないことです。

于 2012-05-01T12:36:12.193 に答える
1

この「AIRNativeExtension」とC++にタグを付けることを考えましたか?box2dとAIRNativeExtensionのどちらも知らないという警告がありますが、おそらく他の人が以前に試みたことをやろうとしているのではないかと思います。例えば:

C++から入力されたポインターまたは構造体をActionscript側に戻すことができません。コンテキストにのみ関連付けることができます...しかし、プリミティブ型を返すことができます

実際にActionscript内でポインターを使用できますか、それとも、インターフェイスに戻すことができるように、ポインターをプリミティブ型で保持しているだけですか?

たぶんこの場合、ポインタをマップのような連想コレクションに格納し、キーをハンドルとして返すことができます。ハンドルを戻すと、C ++側はポインターを検索し、コンテキストを指定して適切にキャストできます。そうすれば、ポインター自体がインターフェースを通過することは決してないので、ポインター関連の問題に対して脆弱になることはありません。

あなたがすでにこれらの線について考えていたならば、お詫びします。

于 2012-05-01T12:55:12.383 に答える
1

多くのサードパーティ API では、このタイプのパターンを使用してデータを渡す必要があります。唯一の問題は、提案したようにintのプリミティブ型を使用する場合、64ビットプラットフォーム用にコンパイルすると、プリミティブ型intが使用可能な最大アドレスを保持しないため、このコードは移植できないことです64 ビット プラットフォームで。この問題を回避するために、32 ビット プラットフォーム用にコンパイルすると 32 ビット、64 ビット プラットフォーム用に 64 ビットになる組み込み型 int_ptr を使用するか、win32 CreateThread 関数または pthread_create 関数のようなプリミティブ型として void* を使用できます。

于 2012-05-01T12:42:29.987 に答える
1

キャストする適切な値はintptr_toruintptr_tですが、アドビにはこれらがあるとは思いません...

したがって、C++ の移植性はさておき、実用的なことを考えると、32 ビット アーキテクチャの場合はunsigned intで問題なく、64ビット アーキテクチャunsigned longの場合は、ポインタの値を保持するのに十分な長さの整数です。そのunsigned部分は安全にプレイするためのものですが、それなしでもプレイできるはずです.

注意しなければならない主なことは、整数型との間でキャストされるポインター型が同一でなければならないということです。つまり、以下は未定義の動作です。

class  A {  };
class B : public A {};

B b;
A *pa = &b;
unsigned x = reinterpret_cast<unsigned>(&a);
B *pb = reinterpret_cast<B*>(x); //UB!

最後の行は次のようになります。

A *pb = reinterpret_cast<A*>(x);

またはそうでなければ:

B *pb = static_cast<B*>(reinterpret_cast<A*>(x));
于 2012-05-01T12:44:07.277 に答える