- ベストアンサー
Delphiの型変換について教えてください
DelphiからRubyプログラムを起動するには ShellExecuteを使えばいけそうなことがわかったのですが、コンパイルでエラーが出ます。 ShellExecute(Handle,'open'、'xxx.rb',OpenDialog1.FileName,syori,SW_SHOWNORMAL)としたのですが TFileNameとPAnsiCharには互換性がありませんとエラーが出ます。 どんな関数を使って変換すればいいのでしょうか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
私の知識不足のためにお手間かけさせてすみませんでした。 (バージョン間の差異についての常識を把握できていないもので。) 結論としては、普通にPCharでキャスト(型変換)すればOkです。 ShellExecute(Handle, 'open', 'xxx.rb', PChar(OpenDialog1.FileName), PChar(syori), SW_SHOWNORMAL); よく分からなかったのは、"PAnsiChar"とエラーが出たことです。(それとバージョン不明) Delphi6ですと、宣言内容と一致する「'TFileName' と 'PChar' には互換性がありません」と出ます。 お手間のおわびにちょっと解説します。 ・ PChar(OpenDialog1.FileName), PChar(syori) これらはPChar型です。OpenDialog1.FileNameはTFileName型ですが、これは TFileName = type string; と宣言されており、実質的にはString型です。syoriはおそらくString型ですよね。それぞれPChar()という形でキャストすることによりPChar型に出来ます。 ・ 'open', 'xxx.rb' これらもPChar型なので PChar('open'), PChar('xxx.rb') として良いのですが…、文字列リテラルの場合はコンパイラが適切に解釈し、宣言に合わせてPChar型と扱ってくれるので 'open', 'xxx.rb' のように省略できます。constで宣言する文字列定数でも同様です。 ・ PChar型はヌルを終端とする文字列へのポインタ型です。C言語等で使われているものと同一です。DelphiではString型をPChar()という形でキャストすることにより、簡単にPChar型を得ることが出来ます。PChar型はAnsi Delphi(D2007以前)ではPAnsiChar型のエイリアス、Unicode Delphi(D2009以降)ではPWideChar型のエイリアスになります。 ・ PAnsiChar型は内部がShift_JIS、ヌルはBYTE型の 0 です。 ・ PWideChar型は内部がUnicode(UTF-16LE)、ヌルはWORD型の0(≒2byteの 0 0)です。
その他の回答 (3)
- pacman_chie
- ベストアンサー率82% (14/17)
言い忘れてましたが、カテゴリが デジタルライフ > ソフトウェア > その他(ソフトウェア) になってますけど、 [技術者向] コンピューター > プログラミング > その他(プログラミング) こっちの方がいいと思います。
お礼
ありがとうございます。 次からはそちらのほうに質問します。
- pacman_chie
- ベストアンサー率82% (14/17)
ううう、、、それはimplementation部(実現部)にある、DLL関数のexternal宣言ですね。 それじゃないんです。 interface部(インターフェース部)にある、{$EXTERNALSYM … とか書かれた行を含む部分です。 今一度、例示と手順を良く見てください。 >その状態で ShellExecute( を検索すれば早いです。 もっと詳しく言うと、 その状態でCtrl+Fを押し、ShellExecute(を検索して探してみてください。 ShellExecuteの後にカッコが付いてます! 実は… バージョンとexternal宣言が確認できた今、9割以上の確信で回答できるのですが、 確実なものにしたいのでShellExecute関数の宣言を確認したいです。
補足
ごめんなさい。 お手数をおかけします。 これでよろしいんでしょうか? {$EXTERNALSYM ShellExecute} function ShellExecute(hWnd: HWND; Operation, FileName, Parameters, Directory: PChar; ShowCmd: Integer): HINST; stdcall; {$EXTERNALSYM ShellExecuteA} function ShellExecuteA(hWnd: HWND; Operation, FileName, Parameters, Directory: PAnsiChar; ShowCmd: Integer): HINST; stdcall; {$EXTERNALSYM ShellExecuteW} function ShellExecuteW(hWnd: HWND; Operation, FileName, Parameters, Directory: PWideChar; ShowCmd: Integer): HINST; stdcall;
- pacman_chie
- ベストアンサー率82% (14/17)
Delphiのバージョンを記載し、コードは手書きでなく必ずコピー&ペーストしてください。 全角記号等が混じってると戸惑いますので。 すぐに回答したいのですが、よく分からない点があるので…、 お手数ですがShellAPI.pasからShellExecute関数の宣言部分(3つあり)を抜き出して提示して下さい。 こんな感じで。(これはDelphi6) ----------------------------------------------------------------- function ShellExecute(hWnd: HWND; Operation, FileName, Parameters, Directory: PChar; ShowCmd: Integer): HINST; stdcall; {$EXTERNALSYM ShellExecuteA} function ShellExecuteA(hWnd: HWND; Operation, FileName, Parameters, Directory: PAnsiChar; ShowCmd: Integer): HINST; stdcall; {$EXTERNALSYM ShellExecuteW} function ShellExecuteW(hWnd: HWND; Operation, FileName, Parameters, Directory: PWideChar; ShowCmd: Integer): HINST; stdcall; ----------------------------------------------------------------- IDE上でShellExecuteにキャレットを置き、右クリック→定義の検索でShellAPI.pasが表示されます。 その状態で ShellExecute( を検索すれば早いです。
補足
回答ありがとうございます。 助かります。 >Delphiのバージョンを記載し、コードは手書きでなく必ずコピー&ペーストしてください。 >全角記号等が混じってると戸惑いますので。 ごめんなさい、以後気をつけます。 Delphiのバージョンは2005です。 関数の宣言部分は function ShellExecute; external shell32 name 'ShellExecuteA'; function ShellExecuteA; external shell32 name 'ShellExecuteA'; function ShellExecuteW; external shell32 name 'ShellExecuteW'; となっています。
お礼
うまくいきました。 ありがとうございます。 解説は、私には難しすぎてよくわかりませんけど...