喫茶XRAYトップページ

[スレッド全体
]

[7915] Re:DLL内の関数のcdecl呼出規約返信 削除
2014/9/9 (火) 15:44:01 Mr.XRAY
> あるのは,作成した関数の引数の型や戻り値の扱い方等です.

おっ,福士さんが.
以下に福士さんが詳しい説明をしています.
この喫茶XRAY に掲載したコードについては,福士さんのコードを参考にしてください.
以下のリンクでコードをみると,欠落部分があります.
実際のメールで確認してください.
(他力本願形式でスミマセン)

http://www.freeml.com/delphi-users/3918

SetLength を実行しないと,たとえ文字列が取得できても,
取得した文字列にゴミが入ることがあります.
サンプルプログラム集のどこかに書いていたのですが... 後で (^^;

# かなり前に,取得した文字列が変だという質問があり,直した記憶があります.

で,元の質問された方の現象の解決策は...  えっと... 分かりません (^^;
UP した,提示したサンプルは,あくまでも cdecl 呼出規約のテストです.
たまたま ML で参考となるのを見かけたのでテストしてみただけです.


[7925] Re2:DLL内の関数のcdecl呼出規約返信 削除
2014/9/10 (水) 13:17:03 Mr.XRAY
> で,元の質問された方の現象の解決策は...  えっと... 分かりません (^^;

敢えて言えば,新規にプロジェクトを作成して,その関係だけの動作を確認することですね.
しかし,そのようなレスをすると,中には,
「何万行ものプログラムの中での操作なので,そのようなことはできません」
返してくる方もいます.
そうなると,返す言葉はありません.
うかつにはレスできないです.

言われた方(質問された方)は,
「何言ってやがんだ.何万行もあるプログラムでそんなことできるわけないだろう.
あんたは,そんな大きなプログラム作ったことないから,そんなこと言えるんだ」
と,気分をがいするかも知れません.
一方,こちらは,「そんなことはなかんべ」と思いますしね.


[7926] Re3:DLL内の関数のcdecl呼出規約返信 削除
2014/9/10 (水) 14:36:16 福士
Delphiでの呼出規約についてはオンラインヘルプの
呼び出し規約 (手続きと関数(Delphi) - RAD Studio)
http://docwiki.embarcadero.com/RADStudio/XE7/ja/%E6%89%8B%E7%B6%9A%E3%81%8D%E3%81%A8%E9%96%A2%E6%95%B0#.E5.91.BC.E3.81.B3.E5.87.BA.E3.81.97.E8.A6.8F.E7.B4.84
が詳しいです。DLLではフツーstdcallだろ、というMr.XRAYさんのご指摘はごもっともでしたので、MLのほうは補足させていただきました。

Win32APIで文字列の取得などを行う関数としては例えば

GetComputerName 関数
http://msdn.microsoft.com/ja-jp/library/cc429732.aspx
GetComputerName function (Windows)
http://msdn.microsoft.com/ja-jp/library/windows/desktop/ms724295.aspx

のように、最大長が予め決まっており、バッファサイズを渡してNUL終端文字列が返されるパターンと、

ExpandEnvironmentStrings 関数
http://msdn.microsoft.com/ja-jp/library/cc429716.aspx
ExpandEnvironmentStrings function (Windows)
http://msdn.microsoft.com/ja-jp/library/windows/desktop/ms724265.aspx

のようにバッファサイズを取得できるので1回バッファをNULL(nil)で呼び出し、必要なサイズにバッファをSetLengthで確保してから
2回目を呼び出し、その後で実際に設定されたサイズでSetLengthし直す、というパターンの2種類があります(他にもShellAPI系のように
メモリ確保を呼び出し先で行い、破棄を呼び出し元で行うようなものもありますが)。

前者はNUL終端文字列を前提としており、Win16以来の比較的古いやり方、後者は比較的新しいやり方、ということになりますね。

Mr.XRAYさんには常識的なことだとは思いますが、まぁ補足(蛇足?)ということで。

[7927] Re4:DLL内の関数のcdecl呼出規約返信 削除
2014/9/10 (水) 15:11:01 Mr.XRAY
▼ 福士さん

うあ,スミマセン.こんなむさ苦しいお店まで足を運んでくださいまして.

> 呼び出し規約 (手続きと関数(Delphi) - RAD Studio)
> http://docwiki.embarcadero.com/RADStudio/XE7/ja/%E6%89%8B%E7%B6%9A%E3%81%8D%E3%81%A8%E9%96%A2%E6%95%B0#.E5.91.BC.E3.81.B3.E5.87.BA.E3.81.97.E8.A6.8F.E7.B4.84


ありゃ,オンラインヘルプにもありましたか.
調べませんでした.

> Mr.XRAYさんには常識的なことだとは思いますが、まぁ補足(蛇足?)ということで。

とんでもないでございます.結構迷いながらやっているもんです.
私にとっても,このお店のお客さんにも参考になると思います.

(1) あらかじめバッファサイズを指定して実行する関数
    取得可能な文字列の長さが決まっている場合
    GetComputerName 関数, GetWindowText 関数等
    FillChar 等でバッファを初期化する(文字列の型の定義による)
    Win16 時代からの,比較的古い関数に多い

(2) 1 回目の実行で,必要なバッファサイズを取得して,あるいは,取得する関数
   結果の Delphi の文字列型の長さは SetLength で設定(指定)する
   比較的新しい方法

という感じですね.
というか,改めて認識しました (^^;
恥ずかしながら,このように体系的にとらえていませんでしたね.
MSDN の関数の記事に,その都度したがっていただけです.
よし!!  サイトのどこかの記事に追加しておこうっと...

# 人様のネタで生きてるサイトの記事と喫茶XRAY でございます.

追記:
言い訳ではではありませんが,別にツッコミじゃぁございませんです(笑)
たまたま,過日,PDF の作成のコードで cdecl を使ったこともあり,
おそらく,多くの方はあまり見かけないのでは,という趣旨です.ハイ.
でも,Delphi のオンラインヘルプに書いてあるんですからね.ハハハッ.


[7928] Re5:DLL内の関数のcdecl呼出規約返信 削除
2014/9/10 (水) 15:50:53 福士
> うあ,スミマセン.こんなむさ苦しいお店まで足を運んでくださいまして.
イツモミテマスヨー

> 言い訳ではではありませんが,別にツッコミじゃぁございませんです(笑)
いや、MLのほうで呼出規約のことは見逃していたので、ここを見て、あー、忘れてたー、と
なったのです。ナイスツッコミでした。

[7929] Re6:DLL内の関数のcdecl呼出規約返信 削除
2014/9/10 (水) 15:55:51 Mr.XRAY
▼ 福士さん

> いや、MLのほうで呼出規約のことは見逃していたので、ここを見て、あー、忘れてたー、と
> なったのです。ナイスツッコミでした。


う〜む.福士さんにそう思わせるきっかけを書くなんて,私も成長したもんだ (^^;


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82