全力わはー RSSフィード

2016-05-06

Oculus SDK 1.3.2 wrapper for Delphi (と、いくつかデモ)

| 00:17 | Oculus SDK 1.3.2 wrapper for Delphi (と、いくつかデモ)を含むブックマーク

f:id:tales:20160506000858g:image

久々に

0.0.1のリリースからかなり間が空きましたが、もうすぐCV1が届くはずなのでリハビリも兼ねてヘッダを移植してみました。

今回はそれに加えて、元々入っているOculusRoomTiny系のデモもいくつか移植しています。コンパイル済みのEXE(64bit用)も入れてあるので、一応Riftさえあればすぐに試せます。

ダウンロード

ちなみに

デモには簡易3Dフレームワークみたいなのが付いてるので、3Dモデルの追加表示程度なら割と簡単にできます*1

f:id:tales:20160506002643g:image

*1:動かすのは別として

2016-04-20

10.1 Berlinのclass helper仕様変更は全然改良じゃないと思った?

| 01:02 | 10.1 Berlinのclass helper仕様変更は全然改良じゃないと思った?を含むブックマーク

皆さんご存じかと思われますが、Delphi 10.1 Berlinがリリースされました。で、新機能の一覧の中にこんなことがさらっと書いてありました。

Delphi コンパイラのその他の改良点
(中略)
可視性のセマンティクスを実行するため、クラス ヘルパやレコード ヘルパでは、拡張元のクラスやレコードの private メンバにはアクセスできません。

なんと、class helperによるprivateメンバーアクセスが制限されてしまいました。class helper内では可視性がprivateとなっていて公開されていないフィールドの読み書きやメソッドのコールなどができるため、VCLやFMXが実装していない機能を自分で追加する時や未修正のバグの対処などで非常に役立つ機能でした。

これが制限されるとなると、こういった処理を記述したソースコードが軒並みコンパイルできなくなるという、バージョン1からの互換性を謳い文句にさえしていたDelphi*1とは思えない愚行です。

とはいえ制限された形でリリースされた以上、何らかの対応を取らなければならないわけで、早速Stack Overflowにも質問が寄せられてるみたいです。しかしそこで回答として寄せられている方法はclass helperを使わずに対処するものなので、それぞれ一長一短があります。

そこで制限を回避して、class helper内からprivateメンバーに再びアクセスする方法を紹介します。

この方法もx86/x64限定という短所はあるにはあるんですが、その代わり以前と同じようにclass helperからprivateメンバーへアクセスすることができます。答えとしては単純なもので、インラインアセンブラを使用するだけです。

unit UnitA;

type
  THoge = class
  private
    FPrivateValue: Integer;
    procedure PrivateMethod;
  end;
end.

unit UnitB;

type
  THogeHelper = class helper for THoge
  public
    function GetValue: Integer;
    procedure CallMethod;
  end;
function THogeHelper.GetValue: Integer;
asm
  MOV EAX,Self.FPrivateValue
end;

procedure THogeHelper.CallMethod;
asm
  CALL THoge.PrivateMethod
end;

このようにインラインアセンブラでアクセスすることで10.1 Berlinで導入された制限を回避できます。

たぶんインラインアセンブラで制限することを忘れてるだけなので、アップデートか何かで塞がれそうな気もしますが、少なくともそれまでの繋ぎとしては使えそうです。

(追記)

メソッドコールは引数があると全部アセンブラ上で積まないといけなくて面倒だと思うので、次のような方法を取るとわりと簡単にコールできます。

type
  THoge = class
  private
    procedure PrivateMethod(Arg1, Arg2, Arg3: Integer);
  end;

// 方法1
// メソッドポインタだけ頂く(メソッドポインタをどこかに代入する必要がある等の場合)
type
  THogePrivateProc = procedure(Self: THoge; Arg1, Arg2, Arg3: Integer);
  THogePrivateMethod = procedure(Arg1, Arg2, Arg3: Integer) of object;
function THogeHelper.GetMethodAddr: Pointer;
asm
  LEA EAX,THoge.PrivateMethod
end;

var
  hoge: THoge;
  proc: THogePrivateProc;
  method: THogePrivateMethod;
begin
  // こっちの方法でもいいし、
  proc := hoge.GetMethodAddr;
  proc(hoge, 1, 2, 3);
  // こっちの方法でもいい
  TMethod(method).Code := hoge.GetMethodAddr;
  TMethod(method).Data := hoge;
  method(1, 2, 3);
end;

// 方法2
// ジャンプさせる(単純に呼び出すだけならこっちが簡単)
procedure THogeHelper.CallMethod(Arg1, Arg2, Arg3: Integer);
asm
  JMP THoge.PrivateMethod
end;

*1:まあ最近は破壊的仕様変更も結構多いけど…

benokbenok 2016/04/20 13:46 すばやい。是非、Stackoverflowにも投稿を(^_^;
なんか、既に下記の「リンク元」を見ると、Google翻訳経由のアクセスが結構あるみたいですね。
今日、仕事終わったら、また投稿しときましょうか?
#以前のUTF8プラグインのの件は、一人からupvoteされましたので、誰かの役に立ったみたいです。

talestales 2016/04/21 00:22 海外の人もよくこんな辺境のブログ見つけますね…(笑)
投稿の件はまたお願いできればありがたいです!

benokbenok 2016/04/21 18:41 遅くなりましたが、投稿してみました。
http://stackoverflow.com/a/36765512/26736
意外とシンプルな文章にまとめるのが難しく、ちょっと時間かかりました(^_^;;

しかし、まったくもって誰得な仕様変更なんでしょうね...。
心の底から理解に苦しみます(笑)

talestales 2016/04/22 23:21 本当ですよね…。
何か技術的な理由でできなくなったのならともかく、
上記のような抜け穴が残ってしまっているということは意図的な制限ですしね。
それはともかく、投稿ありがとうございました。

2015-12-29

プロジェクトをソートするプラグイン。

| 15:55 | プロジェクトをソートするプラグイン。を含むブックマーク

どこぞのフォーラムで「無いの?」って言われてたやーつ。

こんなの

f:id:tales:20151229154926p:image

入手はこちらから

Sort Project Pluginをダウンロード

Sort Project Plugin Ver.0.0.2をダウンロード

2015-12-17

ユニットを新規作成するだけの話。

| 00:01 | ユニットを新規作成するだけの話。を含むブックマーク

この投稿はDelphi Advent Calendar 2015の17日目の記事です。

ところで皆さん何か忘れてませんか?

Object Pascal Advent Calendarじゃないですよ!Delphi Advent Calendarですよ!

もっと開発環境の話もぶっ込んでいきましょう!

(あれ…デジャヴ…?)

ユニットの新規作成

Delphiを使っていれば、当然ユニットなんて掃いて捨てるほど作成していることと思いますが、ここで作成されるコードのカスタマイズって意外とできないんですよね。

フォーム等であればリポジトリ登録してカスタムユニットを新規作成することはできるんですが、やはり通常ユニットを作成した段階で自分好みの状態になっていてくれるのが一番ありがたい。

そこでこのプラグイン

Template Replacerはそういったユニットのテンプレートをカスタマイズ可能にするDelphi XE4〜10 Seattle用プラグインです。

使い方は簡単で、パッケージをインストールしてツールメニューに追加される「Template Replacer」を選ぶだけ。すると以下のような画面が出てくるので、usesにあらかじめよく使うユニットを書いておくだとか、スレッドユニットの余計なお世話なコメントを削除しておくといったように、好きにカスタマイズすることができます*1

f:id:tales:20151216210037p:image

上記画像を見れば一目瞭然ですが、テンプレートの指定は空のユニットに限らず設定可能です。スレッドユニットの作成や、コンソールプロジェクトのソースもカスタマイズできます。そして…。

プロジェクトオプションのカスタマイズ

f:id:tales:20151216210034p:image

「New Project」を選ぶと、dprではなくdprojのテンプレートをカスタマイズすることができます。

dprojはプロジェクトオプションが記述された設定ファイルです。つまりこれがカスタマイズ可能ということは、デフォルトのプロジェクトオプション*2を設定可能ということです。

これを利用すると、例えば「DCC_DcuOutput(ユニットの出力ディレクトリ)」と「DCC_ExeOutput(EXEの出力ディレクトリ)」を自分がよく使うパスに設定しておいたり、ビルド構成にDEBUGとRELEASE以外のものを最初から追加しておく…なんてことも(たぶん)できるようになります。個人的に出力パスの変更はよくやるので、これがあるだけでもかなり楽になります*3

入手はこちらから

Template Replacerをダウンロード

というわけで

このプラグインを導入すれば、あとはユニットを新規作成するだけの話ですね!(タイトル回収)

*1:細かいことだけどend.の後ろに改行があるのが気になるタイプなのでこれで消す作業から解放されるw

*2:プロジェクトオプションダイアログにあったデフォルトチェックボックスって気付いたら無くなってたよね…実はVisibleがFalseになってるだけでまだあるけど

*3:まあ方法は他にもあるみたいですが