Unity向けdll作成及びC言語メモ
この記録について
前職の仕事でc言語でダイナミックライブラリを作成してUnityで使いながらデバッグするということをしていたメモを掘り起こしたもの。
dll関連
dll作る方法
dllMain関数について
dllからはmain関数は呼ばれず、代わりに
dllMainという関数がwindow.hに用意されているらしい。
今回は使わなかったが参考程度に
unity起動中のdll更新
- i-saintさんがいい感じのを作ってくれている
- https://github.com/i-saint/PatchLibrary
 - 使い方はhecomiにのってる
 - 設定が意外とめんどいが後々楽なので最初に入れると便利
 
 
dll側のログを出す方法
使わなかったけどこんな方法あるらしいメモ
c#でstringのメモリを保持して、dll経由でcで書き込む(stringを返す関数をつくる)
このページの文字列を受け取る場合ってところをみる
出力側の関数例
void hoge(char* str, int strlen){
    sprintf_s(str, strlen, "Hello %s\n", "World");
}
dotnet > 4. からStringBuilderにClear関数ができた(らしい)ので積極的に使いたい
cからunity(c#)のコードを呼び出す
vsでビルドするたびにビルド日時を書きだす
何がしたいか
ビルド前に任意のソースコードを生成したい。
まさにこんな感じの
#define BUILD_DATE 20190117140034 
(日付をYYYYMMDDhhmmss形式にしたものを新しくしたい)
何のために
dllを開発してるとこれいつビルドしたやつだっけみたいになって
これほんとに新しいdllかどうか不安になりみたいなことがあったので
dll側に
__declspec( dllexport ) int CheckVersion(){
    return BUILD_DATE //ビルド日時
}
とか書いてあげればdllを使う側からバージョンがチェックできる気がした。
どうやってやるの
結論
- slnがあるディレクトリにdate.batとかつくる
 - date.bat 
echo #define BUILD_DATE "%date% %time%" > date.c - vsで
プロパティ > ビルドイベント > ビルド前のイベントひらく - call $(SolutionDir)date.bat
 - 任意のところで#include "date.c"としてBUILD_DATEを使う
 
何してるか
- ビルドした時の時間でファイルを更新したいのでビルド前のイベントを使う
 - ここでファイルを書き換えてからビルドすればいいはず
 - echoで日付をYYYYMMDDhhmmssにフォーマットして#defineとかつけたりして
 - '>' でファイルに上書き出力すればいい
 - batファイルにする
 - batファイルをたたくのをビルドイベントに設定する
 
はまったポイント
- ビルドイベントにecho書いたらvsの出力に出力されるだけでファイルつくられない。。
 - 使わなかったけどビルドイベントの%のエスケープは%25
 - batファイルはcallをつけて実行する
 - batが実行されるフォルダは$(ProjectDir)なのでbatで出力するディレクトリに注意
 - ディレクトリ間違えるとエラーになる
 
c言語関連
メモリコピー
- memcpyって関数があるらしいよ https://bituse.info/c_func/56
 - 複製というよりもメモリの中の値を別のメモリにコピーって感じだった
 - なので確保してないメモリに使おうとすると止まる
 
スレッドと排他処理
メインスレッド上でforループで永続化するとdll呼び出したときにunityとまる。
スレッド分けましょう
マルチスレッドはCreateThreadを使ったが_beginthreadx使ったほうが安全らしい。
安全してて変えるの怖かったからそのままCreateThreadつかったが。。
構造体
なんとc言語の構造体はtypedef使わないと毎回構造体名の前に"struct"と書かないといけないです。
書くのが普通なんだけど省略のために書くのが普通っぽいですよ
メモリリーク検出
メモリリーク怖い。恐ろしい。
終了時に検出する方法がある
ただ、visual studioの停止ボタンなどで停止すると検出されないので、
適当なタイミングでexit()よんでテストしてみよう!精神的に安心。
あとは地道にコマンドプロンプトで
tasklist /v /fi "imagename eq zForceCalibration.exe"
とかたたいてメモリ使用量が増えていかないかみたりしていた。
テキスト関連
sprintf
visual studioだとsprintfが使えなくて代わりにsprintf_sを使うことになる。
charに文字のサイズ指定して変数をformatして入れてくれる。
printfのラッパー関数つくる
可変引数をもつ関数
入出力関数
Discussion