9

私が理解している背景:Objective-Cメソッドの呼び出しは、基本的に2つの隠しパラメーター(レシーバーとセレクター)を持つC関数呼び出しです。Objective-C ランタイムには、objc_msgSend() という名前の関数が含まれており、その方法でメソッドを呼び出すことができます。残念ながら、関数が構造体を返す場合、特別な処理が必要になる場合があります。構造体が他の値のように返されるのか、それとも最初の非表示の引数で実際に参照によって返されるのかを管理する難解な (非常識と言う人もいるかもしれません) 規則があります。Objective-C の場合、これらの場合に使用する必要がある objc_msgSend_stret() という別の関数があります。

質問: メソッドが与えられた場合、NSMethodSignature または他の何かによって、objc_msgSend() または objc_msgSend_stret() を使用する必要があるかどうかがわかりますか? これまでのところ、NSMethodSignature はこれを認識しており、デバッグ出力に出力することがわかっていますが、パブリック API はないようです。

「どうしてそんなことをしたいの?!」と返信したい場合は、その前に以下をお読みください: https://github.com/erikdoe/ocmock/pull/41

4

3 に答える 3

0

http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.htmlから:

構造体型がレジスタに返すルールは常に不可解であり、時には正気ではありません。ppc32 は自明です: 構造体は決してレジスタに戻りません。i386 は簡単です: sizeof が 1、2、4、または 8 に正確に等しい構造体は、レジスターに戻ります。x86_64 はより複雑で、浮動小数点構造体フィールドを FPU レジスタに返すための規則が含まれており、ppc64 の規則と例外には頭が回転します。悲惨な詳細は Mac OS X ABI ガイドに記載されていますが、いつものように、ドキュメントとコンパイラが一致しない場合、ドキュメントは間違っています。

objc_msgSend を直接呼び出していて、特定の構造体型に objc_msgSend_stret を使用するかどうかを知る必要がある場合は、経験的なアプローチをお勧めします。メソッドを呼び出すコード行を記述し、関心のある各アーキテクチャでコンパイルし、アセンブリ コードを調べて、コンパイラが使用するディスパッチ関数を確認します。

于 2015-05-31T03:51:36.360 に答える
0

NSMethodSignatureには-methodReturnType、戻り値の型が であるかどうかを調べることができる がありstructます。これはあなたがやろうとしていることですか?

于 2013-08-09T10:47:45.520 に答える
0

Objective-C は、特定のアーキテクチャの C と同じ基礎となる ABI を使用します。これは、メソッドが暗黙的selfおよび_cmd引数を持つ単なる C 関数であるためです。

つまり、メソッドがある場合:

- (SomeStructType)myMeth:(SomeArgType)arg;

実際、これは単純な C 関数です。

SomeStructType myMeth(id self, SEL _cmd, SomeArgType arg);

あなたはすでにそれを知っていると確信していますが、私は単に他の読者のために言及しているだけです. SomeStructTypeつまり、libffi または任意の種類の同様のライブラリに、そのアーキテクチャでどのように返されるかを尋ねます。

于 2013-12-01T23:03:22.477 に答える