SlideShare une entreprise Scribd logo
1  sur  39
Télécharger pour lire hors ligne
Runtime C++ Editing
by i-saint
Who am I ?
i-saint / Seiya Ishibashi ( @i_saint )
●
●
●
●

ゲーム屋さん (コンソール系)
仕事では主にシステム&ローレベルプログラミングを担当
趣味でグラフィックスとかも
CPU を全コア無駄なく全力でぶん回すのが生き甲斐
Background Story
ゲーム開発ではよくスクリプト言語が用いられる。これには大き
く 2 つの目的がある。
● トライ&エラーのサイクルを早める
○
○

ゲーム開発では極めて重要
プログラムを再起動せずに変更を反映できる機能はほぼ必須要件

● 非プログラマがゲームの挙動を変更できるようにする
○ チーム開発ではこちらも重要
○ ノベルゲームなどの分野では主にマークアップランゲージが用いられ、専属
のプログラマがつくことは稀、という状況
Background Story
総合型ゲームエンジンの登場
● 総合型ゲームエンジン
○ 乱暴に説明すると、ゲーム用のフレームワーク兼 IDE のようなもの
○ レンダリングエンジン、スクリプトエンジン、レベルエディタ、リソースマネー
ジャなど、ゲーム開発で必要とされる一般的な仕組みを用意
○ Unity 3D や UnrealEngine が有名
Background Story
総合型ゲームエンジンの登場により状況にやや変化
● 非プログラマがゲームの挙動を変更
○
○

この要件はビジュアルスクリプトツールで解決するのが最近のトレンド
UnrealEngine3 の Kismet など

● トライ&エラーのサイクルを早める
○ C/C++ でできるならその方が都合がいいことも多い
○ 実行中に C++ ソースを変更してリアルタイムに反映できたら理想的
○ UnrealEngine4 がこれを実現。ゲーム屋の間に衝撃が走る

UnrealEngine4 登場後、ゲーム屋の間で実行時
C++ 編集がホットなトピックに!
Runtime C++ Editing
いくつかの公開されている実装がある

●
●
●
●

Edit&Continue
libdcompile
RuntimeCompiledC++
DyamicPatcher
Runtime C++ Editing
●
●
●
●

Edit&Continue
libdcompile
RuntimeCompiledC++
DyamicPatcher
Edit & Continue
●
●
●
●

VisualC++ の強力な機能
実行中にデバッガで止めて C++ ソースを編集すると、それを反映しつつ実行を
継続できる
特定のコンパイルオプション (/ZI) をつけてビルドするだけで対応可能
最適化が有効だと使えない、なぜか x64 非対応、などの制限あり
○ 最適化有効だと使えないのはゲーム屋的に痛い
○ x64 非対応も次世代機を考えるといずれ問題になるはず

強力だが、使える状況が限定されている
Runtime C++ Editing
●
●
●
●

Edit&Continue
libdcompile
RuntimeCompiledC++
DyamicPatcher
libdcompile
https://github.com/Fadis/libdcompile
(解説: http://www.slideshare.net/fadis/libdcompile )
@fadis_ さん作。C++ で eval() を実化するライブラリ

1. LLVM & clang を内蔵
2. clang でコンパイル
3. LLVM でリンク & 実行
libdcompile
●
●

●

Windows 非対応なため今回は未検証…
LLVM を使ったものとしては他に Projucer という IDE がある
○ http://www.youtube.com/watch?v=imkVkRg-geI
○ C++ の編集をリアルタイムに反映できるのに加え、ツール上で UI を編集し
たらそれが C++ に反映される、双方向編集を実現している
LLVM 内蔵アプローチは応用範囲が広く、夢が広がる
Runtime C++ Editing
●
●
●
●

Edit&Continue
libdcompile
RuntimeCompiledC++
DyamicPatcher
RuntimeCompiledC++
http://runtimecompiledcplusplus.blogspot.jp/
UnrealEngine4 発表前からあったらしいが、UE4 登場後に広く知られるようになった
代物
1.
2.
3.

インターフェース class を定義し、編集可能にしたい部分を継承した class に閉
じ込め、DLL に分離
C++ ソースを更新したら DLL をビルド
対象 DLL に属するオブジェクトをシリアライズし、DLL をリロードし、オブジェクト
をデシリアライズ
RuntimeCompiledC++
● DLL のビルド
○

ごく普通に VisualC++ のコンパイラ (cl.exe) を呼んでいる

● DLL に属するオブジェクトのシリアライズ
○
○

面倒だがデータ構造に変更がなくても必要
そうしないと vftable が更新されず、古い dll の関数を呼びに行こうとして死
ぬ
RuntimeCompiledC++
pros:
● 実装がシンプルかつ堅実
● 多くのプラットフォームで実現可能
cons:
● class の更新に serialize が必須
● DLL 毎にプロジェクトを分離するのが面倒
UnrealEngine4 の HotReload はこれと同じようなアプローチだと推測される。
RuntimeCompiledC++
pros:
● 実装がシンプルかつ堅実
● 多くのプラットフォームで実現可能
cons:
● class の更新に serialize が必須
● DLL 毎にプロジェクトを分離するのが面倒
こやつらをなんとかしたい。もっとお手軽に使えるようにしたい。
Runtime C++ Editing
●
●
●
●

Edit&Continue
libdcompile
RuntimeCompiledC++
DyamicPatcher
DynamicPatcher
https://github.com/i-saint/DynamicPatcher
今回の話のメインディッシュ。
RuntimeCompiledC++ に不満があった&面白そうな別のアプローチを思いついた
ので作ってみました。

1. C++ ソースを更新したらコンパイル
2. .obj ファイルを自力でロード&リンク
3. 古い関数を新しい関数への jmp に書き換えて更新
DynamicPatcher
1. C++ ソースを更新したらコンパイル
2. .obj ファイルを自力でロード&リンク
3. 古い関数を新しい関数への jmp に書き換えて更新
DynamicPatcher
1. C++ ソースを更新したらコンパイル
● 更新の監視
○
○

専用スレッドで FindFirstChangeNotification()
ここは RuntimeCompiledC++ と同じ

● コンパイル
○
○
○

msbuild を呼ぶだけ。GNU 系ツールで言うところの make
.vcxproj ファイルは makefile の機能も果たしている
コンパイルだけしたい場合 “/target:ClCompile” を指定
DynamicPatcher
1. C++ ソースを更新したらコンパイル
2. .obj ファイルを自力でロード&リンク
3. 古い関数を新しい関数への jmp に書き換えて更新
Load & Link .obj Files
.obj はフォーマットが公開されており、比較的わかりやすい構造なため、自力でロー
ド&リンクして中にある関数を実行できるようにするのはそこまで難しくはない。
(資料 http://www.skyfree.org/linux/references/coff.pdf )
大雑把には以下の手順

1. ファイルの内容を section を再配置しつつメモリ上にマップ
2. relocation 情報を元にシンボルをリンク
Load & Link .obj Files
1. section を再配置しつつメモリ上にマップ
●
●
●

.obj ファイルは section と呼ばれるブロックで構成される
section 毎に色んな属性と情報が付随する
○ 読み取り専用データ、実行コード、デバッグ情報、etc
align 指定がある section があり、.obj ファイルの状態では align を考慮した配
置になっていない。自力で再配置する必要がある
○ これを怠ると __m128 の literal を参照とかで謎のクラッシュが起きる
○ VirtualAlloc() で確保した、実行可能属性付きの領域に section の内容を
移していけば ok
Load & Link .obj Files
2. relocation 情報を元にシンボルをリンク
●
●
●
●

●

relocation 情報: リンク時にここにあのシンボルのアドレスを書き込んでね、とい
う情報
この情報に従ってアドレスを書き込んでいけばリンクが完了する
.obj 内にあるシンボルは .obj のシンボルテーブルから見つけられる
ホストプログラムのシンボルは dbghelp の SymFromName() で取得
○ .pdb が必要になる
○ この API は猛烈に遅く、最初のリンクはやや時間がかかってしまう
特定のシンボルは常にホストプログラムのシンボルでリンクする機構も用意
○ singleton の getInstance() などで必要になる
Load & Link .obj Files
制限事項
●

●

●
●

/LTCG (リンク時コード生成) オプションでコンパイルされた .obj は対応不可
○ 通常と異なるファイルフォーマットになるため
○ VisualC++ のツールチェイン (dumpbin) ですら情報を出せない
/GR (RTTI 有効) でコンパイルされた .obj は危険
○ vftable の構造が変わる
○ .obj の時点では最初の要素が RTTI 情報へのポインタになっている
○ 通常実行時は 1 個前にずれて -1 番目が RTTI 情報になっている
○ 再現する方法がわからず未対応
○ 幸いゲーム屋は RTTI 使わないことが多い
global オブジェクトのコンストラクタ問題
○ atexit() でデストラクタを呼ぶ処理を登録するため危険。非対応。
デバッガでソースを追えない
○ かなしい
DynamicPatcher
1. C++ ソースを更新したらコンパイル
2. .obj ファイルを自力でロード&リンク
3. 古い関数を新しい関数への jmp に書き換えて更新
Patching Functions
古い関数を新しい関数への jmp に書き換えて更新
●

●

関数の先頭 5 byte を新しい関数への jmp に書き換える
○ x86 には命令自身に飛び先アドレスを含められる jmp 命令がある
○ これを使うとレジスタの内容を変えずに制御を飛ばせるため、同じ型の引
数の別の関数に簡単にリダイレクトさせることができる
関数のアドレスは変わらないので vftable の更新が必要なくなり、シリアライズ
なしで class の挙動を更新しつつ実行継続できる
○ データ構造が変わる変更はさすがに無理。ユーザー側の対応が必要
○ シリアライズとか事前に余剰スペースを設けてなんとかするとか
Patching Functions
古い関数も呼べるようにする
●
●

●

hook 的に使いたいことがたまにあるため対応
更新前の 5 byte を含む命令を別の場所に退避させ、末尾に元の場所への jmp
を書き加えておく
○ このコード片を call すれば更新前の関数が実行される
○ これを実装するのは結構しんどい。x86 は命令が可変長なので、命令を正
しく解釈して 5 byte を含む命令がどこまでか調べる必要がある
○ 相対アドレスを含む命令を含む場合つなぎ変えも必要
○ 幸い命令の解釈はライブラリ (tDisasm) があったのでそれを使用した
MHook の実装が参考になる
○ http://codefromthe70s.org/mhook23.aspx
○ tDisasm は MHook に含まれる
Patching Functions
その他注意点
●

●

x64 の場合、相対アドレスが 32bit を超えるケースへの対処が必要
○ 64bit absolute indirect jump なる命令があるので、これをトランポリンコー
ドとして挟む
■ 古い関数->トランポリン->新しい関数
○ 古い関数に直接 64bit absolute indirect jump を書き込んでもいいが、14
byte 必要なためやや危険
.obj をロードした時どの関数を更新するか?
○ 問答無用で全部更新するのは危険だし無駄が多い
○ dllexport は .obj に情報が残るのでそれを利用
○ dllexport (を包んだマクロ) をつけたシンボルを自動更新するという仕様に
○ プログラム開始時点でついてる必要はないため、多少ユーザーに手間をか
けることになるが致命的な制限にはならないと判断
DynamicPatcher
pros:
● ほとんど前準備なしに実行時C++編集可能
cons:
● たぶん x86(64) 限定
○

レジスタの内容変えず jmp できる特性から

● obj ロードによる制約
○
○
○

デバッガでソースを追えない
規模が大きくなるとリンク時間が長くなる
/LTCG 禁止などの奇妙な制限

お手軽に使えるのは強力なメリットだが、制限がやや痛い。
Dealing with .dll
dll との併用
●

●
●

.obj の制限は .dll なら解決できる
○ デバッガでソース追えない -> dll なら可能
○ リンク遅い -> dll ならビルド時に完了してる
○ 奇妙なコンパイルオプション制限 -> dll なら必要なし
.obj も .dll も透過的に扱えれば状況に応じて使い分けができる
プロジェクト分離する手間はかかるが、どちらにせよ規模が大きくなってきたら
dll への分離が必要に迫られることが多い
○ ビルド & リンク時間削減、リンク時メモリ使用量削減などのため
Dealing with .dll
dll 対応
●
●
●
●

ExportAddressTable を巡回すれば dllexport なシンボルを巡回できる
あとは .obj 同様、古い関数の先頭を新しい関数への jmp に書き換えるだけ
○ dll->dll の関数書き換えだと .pdb すら不要
RuntimeCompiledC++ と違い、シリアライズ不要の恩恵は残る
○ 関数のアドレスは変わらない、という違いから
ここまでは簡単だが…
Dealing with .dll
ファイルロック問題
●

●

ロードされている dll は対応する pdb と共にロックがかかる
○ ビルドしてできた dll をそのままロードすると、pdb へ書き込めなくなって以
降のビルドが失敗する
○ この問題を回避するため、ロードする前に dll & pdb を適当にリネーム&コ
ピーする必要がある
○ このとき、dll の中にある pdb へのフルパスと GUID、および pdb の中にあ
る GUID を更新する必要がある
■ GUID についてはやや複雑な事情があるが、こうしないとデバッガが
正しいシンボル情報を読めないことがある
この対応が大変
Dealing with .lib
ついでに .lib にも対応
●
●

.obj が数珠つなぎになっただけの構造なので簡単
○ http://hp.vector.co.jp/authors/VA050396/tech_04.html
インポートライブラリは未対応だが、dll 直接読めるので無問題
DynamicPatcher
pros:
● ほとんど前準備なしに実行時C++編集可能
cons:
● たぶん x86(64) 限定
○

レジスタの内容変えず jmp できる特性から

● obj ロードによる制約
○
○
○

デバッガでソースを追えない
規模が大きくなるとリンク時間が長くなる
/LTCG 禁止などの奇妙な制限

.obj ロードのお手軽さはそのまま、必要に応じて .dll に切り替えることも可能に。
DynamicPatcher
今後こんなことができたらいいなリスト
●
●
●
●

.obj のリンク高速化
○ .pdb を自力で解釈するとか
.obj のままデバッガでソース追う
○ 不可能ではないと思う…けど難しそう
POSIX 系 OS 対応
○ できるはず
ARM 対応
○ 不可能?求む情報
Conclusion

C++ は動的言語
(デバッグ情報が使えれば)
End
thank you for watching!
Supplement
発表後の質問等を受けての追記
● 関数書き換え時にスレッド止めたりの対応はしてる?
○
○

現状やってないが、やったほうがいいのは確か
メインループのどこかで更新関数を呼ばせる構造になっているため、大抵
のケースでは問題は起きない

● .obj 内の例外処理
○
○

例外処理は全く考えてなかったが、対応は一筋縄ではいかないらしい
幸いゲーム屋は例外ほとんど使わない!

● /hotpatch はいかが?
○
○

諸々の事情により使用を見送った
ユーザーにこのオプションを要求したくない、/hotpatch 未対応の既存の
コードを書き換えたいケースもある、x64 だと /hotpatch 使っても hook 処
理は簡単には実現できない、等など

● ARM 対応
○
○

可能らしい
register 全部 push とかの命令がある

Contenu connexe

Tendances

Tendances (20)

UE4のためのより良いゲーム設計を理解しよう!
UE4のためのより良いゲーム設計を理解しよう!UE4のためのより良いゲーム設計を理解しよう!
UE4のためのより良いゲーム設計を理解しよう!
 
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
 
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
 
Assembly Definition あれやこれ
Assembly Definition あれやこれAssembly Definition あれやこれ
Assembly Definition あれやこれ
 
Mask Material only in Early Z-passの効果と仕組み
Mask Material only in Early Z-passの効果と仕組みMask Material only in Early Z-passの効果と仕組み
Mask Material only in Early Z-passの効果と仕組み
 
Game Creators Conference 2019 Keiji Kikuchi
Game Creators Conference 2019 Keiji KikuchiGame Creators Conference 2019 Keiji Kikuchi
Game Creators Conference 2019 Keiji Kikuchi
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
Boost Fusion Library
Boost Fusion LibraryBoost Fusion Library
Boost Fusion Library
 
良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方
 
中級グラフィックス入門~シャドウマッピング総まとめ~
中級グラフィックス入門~シャドウマッピング総まとめ~中級グラフィックス入門~シャドウマッピング総まとめ~
中級グラフィックス入門~シャドウマッピング総まとめ~
 
トリコの動かし方
トリコの動かし方トリコの動かし方
トリコの動かし方
 
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理
 
MagicOnion入門
MagicOnion入門MagicOnion入門
MagicOnion入門
 
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
 
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
 
MRTK-Unreal(UX Tools) を利用した HoloLens 2 アプリ開発 | UNREAL FEST EXTREME 2020 WINTER
MRTK-Unreal(UX Tools) を利用した HoloLens 2 アプリ開発 | UNREAL FEST EXTREME 2020 WINTERMRTK-Unreal(UX Tools) を利用した HoloLens 2 アプリ開発 | UNREAL FEST EXTREME 2020 WINTER
MRTK-Unreal(UX Tools) を利用した HoloLens 2 アプリ開発 | UNREAL FEST EXTREME 2020 WINTER
 
モバイルアプリにおけるアーティストフレンドリーな水面表現戦略
モバイルアプリにおけるアーティストフレンドリーな水面表現戦略モバイルアプリにおけるアーティストフレンドリーな水面表現戦略
モバイルアプリにおけるアーティストフレンドリーな水面表現戦略
 
初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)
初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)
初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)
 
UE4における大規模背景制作事例 描画特殊表現編
UE4における大規模背景制作事例 描画特殊表現編UE4における大規模背景制作事例 描画特殊表現編
UE4における大規模背景制作事例 描画特殊表現編
 

Similaire à Runtime c++editing

DLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミングDLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミング
terurou
 
130522 rt講習会(説明用)
130522 rt講習会(説明用)130522 rt講習会(説明用)
130522 rt講習会(説明用)
openrtm
 
griffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jgguggriffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jggug
kimukou_26 Kimukou
 
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
Hirotaka Kawata
 

Similaire à Runtime c++editing (20)

【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜
【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜	【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜
【とらのあなラボ Tech Day #3】新規システムにおける技術選定〜GoとgRPCを採用した話〜
 
OCaml でデータ分析
OCaml でデータ分析OCaml でデータ分析
OCaml でデータ分析
 
Linux kernelのbspとupstream
Linux kernelのbspとupstreamLinux kernelのbspとupstream
Linux kernelのbspとupstream
 
自作コンピューターでなんかする - 第八回 カーネル/VM探検隊&懇親会
自作コンピューターでなんかする - 第八回 カーネル/VM探検隊&懇親会自作コンピューターでなんかする - 第八回 カーネル/VM探検隊&懇親会
自作コンピューターでなんかする - 第八回 カーネル/VM探検隊&懇親会
 
Golang tokyo #7 qtpm
Golang tokyo #7 qtpmGolang tokyo #7 qtpm
Golang tokyo #7 qtpm
 
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコムResemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
Resemaraを支えた技術 フライングゲットガチャの舞台裏 #ksgstudy #ドリコム
 
DLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミングDLR言語によるSilverlightプログラミング
DLR言語によるSilverlightプログラミング
 
Bjarne dont speaking
Bjarne dont speakingBjarne dont speaking
Bjarne dont speaking
 
130522 rt講習会(説明用)
130522 rt講習会(説明用)130522 rt講習会(説明用)
130522 rt講習会(説明用)
 
ゆるふわLinux-HA 〜PostgreSQL編〜
ゆるふわLinux-HA 〜PostgreSQL編〜ゆるふわLinux-HA 〜PostgreSQL編〜
ゆるふわLinux-HA 〜PostgreSQL編〜
 
Hyperledgerのチュートリアルで理解する基幹システム向けブロックチェーンハンズオン
Hyperledgerのチュートリアルで理解する基幹システム向けブロックチェーンハンズオンHyperledgerのチュートリアルで理解する基幹システム向けブロックチェーンハンズオン
Hyperledgerのチュートリアルで理解する基幹システム向けブロックチェーンハンズオン
 
C#メタプログラミング概略 in 2021
C#メタプログラミング概略 in 2021C#メタプログラミング概略 in 2021
C#メタプログラミング概略 in 2021
 
nadoka さんの m17n 対応のベストプラクティス
nadoka さんの m17n 対応のベストプラクティスnadoka さんの m17n 対応のベストプラクティス
nadoka さんの m17n 対応のベストプラクティス
 
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
 
griffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jgguggriffon plugin を 実際に作ってみよう #jggug
griffon plugin を 実際に作ってみよう #jggug
 
Rdkitの紹介
Rdkitの紹介Rdkitの紹介
Rdkitの紹介
 
続・PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜 #2
続・PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜 #2続・PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜 #2
続・PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜 #2
 
20191120 beyondstudy#21 kitaoka
20191120 beyondstudy#21 kitaoka20191120 beyondstudy#21 kitaoka
20191120 beyondstudy#21 kitaoka
 
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
 
20130316 プログラミング言語Go
20130316 プログラミング言語Go20130316 プログラミング言語Go
20130316 プログラミング言語Go
 

Runtime c++editing