将C ++(。dll)与C#Unity脚本

时间:2016-11-14 08:29:16

标签: c# c++ unity3d dll

我正在尝试将本机代码(c ++项目)作为.dll与C#unity脚本同步。 原生代码:

Audio.h:

#pragma once
#include <iostream>
#define EXPORT __declspec(dllexport)

extern "C" {    
    EXPORT void initialize(std::string soundFilePaths[]);
    EXPORT void setSourcePosition(std::string soundFilePath, float x, float y, float z);
    EXPORT void play();
    EXPORT void stop();
    EXPORT void setListenerRotation(float x, float y, float z);
}

class Audio {

public:

    static Audio& instance() {  // Singleton
        static Audio INSTANCE;
        return INSTANCE;
    }

    void initialize(std::string soundFilePaths[]);
    void setSourcePosition(std::string soundFilePath, float x, float y, float z);
    void play();
    void stop();
    void setListenerRotation(float x, float y, float z);
    ~Audio();

private:    
    Audio();
};

Audio.cpp:

#include "Audio.h"

extern "C" {    

    void initialize(std::string soundFilePaths[]) {
        Audio::instance().initialize(soundFilePaths); 
    }

    void setSourcePosition(std::string soundFilePath, float x, float y, float z) {
        Audio::instance().setSourcePosition(soundFilePath, x, y, z);
    }

    void play() {
        Audio::instance().play();
    }

    void stop() {
        Audio::instance().stop();
    }

    void setListenerRotation(float x, float y, float z) {
        Audio::instance().setListenerRotation(x, y, z);
    }
}

Audio::Audio()
{
}

Audio::~Audio()
{
}

void Audio::initialize(std::string soundFilePaths[])
{   
}

void Audio::setSourcePosition(std::string soundFilePath, float x, float y, float z)
{

}

void Audio::play()
{
}

void Audio::stop()
{
}

void Audio::setListenerRotation(float x, float y, float z)
{
}

Unity C#脚本如下:

using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

public class AudioPlugin : MonoBehaviour
{
    public AudioContainer[] audioContainers;
    //public AudioClip[] audioFiles;
    //public Transform[] audioSources;
    public Transform headGeometry;
    public float rotationSpeed = 50;
    public float maxYRotation = 90;
    public float minYRotation = -90;
    float _currentYRotation;

    void Start()
    {
        _currentYRotation = headGeometry.transform.rotation.eulerAngles.y;
        string[] filePaths = GetAllFilePathsFromClips();
        AudioPluginConnection.Initialize(filePaths);
        AudioPluginConnection.Play();
    }

    void Update()
    {
        TurnHeadWithInput();
        UpdateListenerRotation();
        UpdateSoundPositions();
    }

    void OnDestroy()
    {
        AudioPluginConnection.Stop();
    }

    void TurnHeadWithInput()
    {
        float horizontal = Input.GetAxis("Horizontal");
        horizontal *= Time.deltaTime * rotationSpeed;
        _currentYRotation = Mathf.Clamp(_currentYRotation + horizontal, minYRotation, maxYRotation);
        Vector3 eulerAngles = headGeometry.rotation.eulerAngles;
        eulerAngles.y = _currentYRotation;
        headGeometry.rotation = Quaternion.Euler(eulerAngles);
    }

    void UpdateListenerRotation()
    {
        Vector3 eulerAngles = headGeometry.rotation.eulerAngles;
        AudioPluginConnection.SetListenerRotation(eulerAngles.x, eulerAngles.y, eulerAngles.y);
    }

    void UpdateSoundPositions()
    {
        foreach (AudioContainer container in audioContainers)
        {
            Vector3 position = container.source.position;
            AudioPluginConnection.SetSourcePosition(container.filePath, position.x, position.y, position.z);
        }
    }

    string[] GetAllFilePathsFromClips()
    {
        List<string> audioFilePaths = new List<string>();
        foreach (AudioContainer container in audioContainers)
        {
            audioFilePaths.Add(container.filePath);
        }
        return audioFilePaths.ToArray();
    }
}

[System.Serializable]
public class AudioContainer
{
    public AudioClip clip;
    public Transform source;
    public string filePath { get { return Application.dataPath + "/Audio/" + clip.name + ".wav"; } }
}

public class AudioPluginConnection
{
    [DllImport("AudioPlugin", EntryPoint = "test")]
    public static extern int Test();
    [DllImport("AudioPlugin", EntryPoint = "initialize")]
    public static extern void Initialize(string[] soundFilePaths);
    [DllImport("AudioPlugin", EntryPoint = "setSourcePosition")]
    public static extern void SetSourcePosition(string soundFilePath, float x, float y, float z);
    [DllImport("AudioPlugin", EntryPoint = "play")]
    public static extern void Play();
    [DllImport("AudioPlugin", EntryPoint = "stop")]
    public static extern void Stop();
    [DllImport("AudioPlugin", EntryPoint = "setListenerRotation")]
    public static extern void SetListenerRotation(float x, float y, float z);
}

每次我尝试运行统一场景时,Unity程序都会崩溃。我认为问题出在本机代码中,因为我真的不知道如何将类和方法导出到.dll。 我的假设是,也许字符串(我用它作为两个方法的参数)不起作用,因为当我用字符串返回值创建一个测试方法时程序也崩溃了。但我不确定。

我想知道为什么我的程序崩溃以及如何同步这两个代码(c ++和c#)。

提前谢谢

0 个答案:

没有答案