【发布时间】:2016-11-14 08:29:15
【问题描述】:
我正在尝试将本机代码(c++ 项目)作为 .dll 与 C# 统一脚本同步。 本机代码:
音频.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();
};
音频.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 场景时,Unity 程序都会崩溃。我认为问题出在本机代码中,因为我真的不知道如何将类和方法导出到 .dll。 我的假设是字符串(我已将其用作两种方法的参数)可能不起作用,因为当我使用字符串返回值创建测试方法时程序也崩溃了。但我不确定。
我想知道我的程序为什么会崩溃以及如何同步两个代码(c++ 和 c#)。
提前谢谢你
【问题讨论】:
-
看看this one。
-
您也可以尝试使用 c++/cli bridge 和 marshaing lib 来实现此目的。 pragmateek.com/using-c-from-native-c-with-the-help-of-ccli-v2