むずかしいことはわかりません

いろいろ書いてるみたいな

void *でポインタを渡してパラメータを得る場合

C#C++で書いたDLLを連携するときのメモ

 

DLL側の関数

DLL_API void setDataToBuffer(void *vp) {
     *((int *)vp) = 5;
}

C#側の処理

// 宣言

[DllImport("DLLの名前")]

static extern void setDataToBuffer(IntPtr p);

 

// ボタンでテストしたのでその処理

private void button6_Click(object sender, EventArgs e)
{

  // データを保存する領域を確保する
  IntPtr buf = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(Int32)));

 

  // DLL呼び出し

  setDataToBuffer(buf);

 

  // Marshalで書き込まれているIntPtrの内容を読み出し 

  textBox6.Text = Marshal.ReadInt32(buf).ToString();

  // allocしたメモリを解放

  Marshal.FreeCoTaskMem(buf);
}

毎回、Allocするのやだなーと思うので、改良できないのか考えてみる

 

スクリプト側のpublicなGameObjectをEditorで設定するとき

public GameObject anyObjects;

とやると、Editor側に

Any Objects みたいなパラメータ設定がでてくるので、そこで参照(Θみたいなとこをクリック)して選んだときに選んだものがprefabだと実行時エラーが出てうまく動かないので、必ずHierarchyビューの中にいるオブジェクトをドラッグドロップしましょう。

 

という話。

 

スクリーンショットなどはのちほど。

 

基底クラスの呼び出し

Javaでは、 super() とか super.メソッド()と書くアレ

C#では、 base.メソッド() と書く。 base()ではないらしい。

 

UnityでもMonoBehaviourが基底となってるクラス作ってもoverrideして、呼び出せる

 

public class AnyClass : MonoBehaviour {

  public virtual Start() {

    // 初期化処理

  }

 

  public virtual Update() {

  //フレーム処理

  }

}

 

public class OtherClass: AnyClass {

  public override Start()  {

    base.Start();

  }

 

  public override Update() {

    base.Update();

  }

}

 

Updateはともかくとして、Startを呼び出せると共通初期化処理はそのままにしておける。それから、MonoDevelopだと継承したクラス側でそれぞれのメソッド作ると、勝手にbase.メソッド()を補完してくれる。

(Unity側でC# Script作ってると最初からStartやUpdateがあるので、書かれないけど)

 

C++で作ったDLLをUnityから呼び出すに当たって設定するのめんどくさいって話

C#(Unity)側でやること

static extern をつけなくてはいけない。
DllImport は using System.Runtime.InteropServices; すること
IntPtr は using System; すること

C++(DLL)側でやること

extern "C" { } でCのスタイルでリンクする

VisualStudio Community 2013では、デフォルトでDLLを作るとWindows8.1とWindowsPhone用のファイルを作ろうとするので、Win32のウィザードを起動してDLL作る設定にする

 

[141127追記]

C++の構造体をC#で受け取る方法というか、IntPtrを受け取ったあとにそれをどういう形で処理するかっていう話で結局Marshalが一番現実的かという話なんだけど


ポインタ(バイト配列)から構造体への変換 - schima.hatenablog.com

 

 C++側のポインタにアクセスする場合はC#側はIntPtrを使う

Marshal.PtrToStructureを使うことで、あんまり考えなくてよくなった。

 

floatのバイト数がC++C#で違うかどうか → http://www.kumei.ne.jp/c_lang/cs/cs_05.htm

 C++側のfloatを取り出してもC#側では、ふつーに表示されていたので、問題なさそう

キーコードから #PC-6601SR のキーボードの信号らしきものに変換する

もりやさんが

という、キーボードの信号のビット列についての資料を出していたので、キーコードからビット列に直すやつ、C#で適当に書いといた。

namespace IRCnv

{
  public partial class Form1 : Form
  {
  public Form1()
  {
    InitializeComponent();
  }

  // 000_0000_0000_0_000_0000_0000_0_0 24+1
  private const int BITBUF_SIZ = 25; // #define BITBUF_SIZ 25
  private const int SIGNAL_START = 0; // #define SIGNAL_START
  private const int CHR_START = 3; // #define CHR_START 3
  private const int LOWER_BIT_FLAG = 11; // #define LOWER_BIT_FLAG 11
  private const int NEGATIVE_CHR_OFFSET = 12; // #define NEGATIVE_CHR_OFFSET 12
  private const int STOP_BIT = BITBUF_SIZ - 1; // #define STOP_BIT (BITBUF_SIZ - 1)

  private String IRCode(char keychar)
  {
    int code = (int)keychar & 0xff;
    int[] bitbuf = new int[BITBUF_SIZ]; // 1バイトを8ビットに変換する

    // 下位→上位
    for (int i = 0; i < 8; ++i)
    {
      // キーコード8bitを下位から
      bitbuf[i + CHR_START] = (code & 1);
      bitbuf[i + CHR_START + NEGATIVE_CHR_OFFSET] = ~(code & 1) & 1;

      code >>= 1;
    }

      bitbuf[SIGNAL_START] = bitbuf[SIGNAL_START + 1] = bitbuf[SIGNAL_START + 2] = 0;
      bitbuf[SIGNAL_START + 0 + NEGATIVE_CHR_OFFSET] =
      bitbuf[SIGNAL_START + 1 + NEGATIVE_CHR_OFFSET] =
      bitbuf[SIGNAL_START + 2 + NEGATIVE_CHR_OFFSET] = 1;

      bitbuf[LOWER_BIT_FLAG] = bitbuf[CHR_START];
      bitbuf[LOWER_BIT_FLAG + NEGATIVE_CHR_OFFSET] = ~bitbuf[CHR_START] & 1;

      bitbuf[STOP_BIT] = 0;

      return String.Join("", bitbuf);
    }

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
      textBox1.AppendText(e.KeyChar + ":" + IRCode(e.KeyChar) + Environment.NewLine);
    }
  }
}

 

textBox1をForm1に貼って、Readonlyにして動かすとtextbox上で打ったキーを変換したものをtextboxに追加していきます。

 a:0001000011011110111100100
b:0000100011001111011100110
c:0001100011011110011100100
d:0000010011001111101100110
e:0001010011011110101100100
f:0000110011001111001100110
g:0001110011011110001100100
こんなかんじ。

Touchクラスイベント

イベント(phase)の種類

Began:パネルに指がついた状態

Stationary:パネルに指はあるけど、指が動いていない状態

Moved:指が動いている状態

Ended:指がパネルから離れた状態


Unity - Scripting API: TouchPhase 

 

位置、移動量などの種類

position:スクリーン座標

rawPosition:(出てくるけど、解説がない)

deltaPosition:移動量

 

↓まだ試してない

deltaTime:(最後に記録された部分からの経過時間)

fingerId:タッチの 個別index

tapCount:タップした回数


Unity - Scripting API:

 

とりあえず、タッチした瞬間にBeganになって、しばらくするとStationaryが来る。

移動を開始するとMovedになり、指が離れた瞬間にEndedになる。

 

移動量が知りたければ、deltaPosition

位置が知りたければ、position

 

テストプログラムの実行結果↓

 

画面の上下が違う感じがするんだけど、これはなんだろな。