3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++で作成した配列を返すDLLをUnity(C#)で適切に受け取る

Last updated at Posted at 2018-01-21

したいこと

C++で作成した、配列を返すDLLをUnity(C#)で受け取る方法を考察します。

前提

開発環境:Unity 2017 + Visual Studio Community 2017
言語:Unity C#, C++

使用するDLL

C++で以下のコードで生成されたDLLを使用します。
C++の配列の使い方が間違っている気がする汚いコードです。

DllForDebug.cpp
#include "stdafx.h"
#include "DLLForDebug.h"
#include "iostream"
// グローバル変数
int* arr = new int[5];
float* arr_float = new float[5];
char* arr_char = new char[5];
// {0, 1, 2, 3, 4}のint型配列を返す
int* ReturnIntArray()
{
    int i = 0;
    for (i = 0; i <= 4; i++)
    {
        arr[i] = i;
    }
    return arr;
}
// {0, 0.75, 1.50, 2.25, 3}のfloat型配列を返す
float* ReturnFloatArray()
{
    int i = 0;
    for (i = 0; i <= 4; i++)
    {
        arr_float[i] = i * 0.75;
    }
    return arr_float;
}
// {a,i,u,e,o}のchar型配列を返す
char* ReturnCharArray()
{
    arr_char[0] = 'a';
    arr_char[1] = 'i';
    arr_char[2] = 'u';
    arr_char[3] = 'e';
    arr_char[4] = 'o';
    return arr_char;
}
DllForDebug.h
extern "C"
{
    __declspec(dllexport) int* ReturnIntArray();
    __declspec(dllexport) float* ReturnFloatArray();
    __declspec(dllexport) char* ReturnCharArray();
}

Unity上での動作

以下のソースファイルを使用して、Unity上での実行を確認しました。
ここで使用する「Marchal.Copy」についての詳細は、MSDNを参照してください。

RunDLL.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// IntPtr型を使用するのに必要
using System;
// Dllの読み込みに必要
using System.Runtime.InteropServices;
public class RunDLL : MonoBehaviour
{
    // Dll内の関数を宣言
    [DllImport("DllForDebug")]
    private extern static IntPtr ReturnIntArray();
    [DllImport("DllForDebug")]
    private extern static IntPtr ReturnFloatArray();
    [DllImport("DllForDebug")]
    private extern static IntPtr ReturnCharArray();
    
    // Use this for initialization
    void Start()
    {
        int i = 0;
        // 格納したい配列先
        int[] arrInt = new int[5];
        float[] arrFloat = new float[5];
        char[] arrChar = new char[5];
        // 配列の先頭ポインタをIntPtr型の変数にそれぞれ格納する
        IntPtr ptrInt = ReturnIntArray();
        IntPtr ptrFloat = ReturnFloatArray();
        IntPtr ptrChar = ReturnCharArray();
        // コピー
        Marshal.Copy(ptrInt, arrInt, 0, 5);
        Marshal.Copy(ptrFloat, arrFloat, 0, 5);
        Marshal.Copy(ptrChar, arrChar, 0, 5);
        // Log
        for (i = 0;i <=4; i++)
        {
            Debug.Log(arrInt[i]);
            Debug.Log(arrFloat[i]);
            Debug.Log(arrChar[i]);
        }
    }
    // Update is called once per frame
    void Update()
    {
    }
}

#結果と問題
Consoleを確認すると、int型とfloat型は正確な情報を手に入れることが確認できます。
何故かchar型が上手くいかない問題…

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?