如何轻松地将c ++代码添加到Unity项目中?

时间:2016-10-18 11:09:58

标签: c# c++ unity3d dll

所以,我正在尝试在Unity中构建一个应用程序,这需要分子可视化。有一些库可用于估计分子的特性,读取分子,写分子等。但是可视化很少。 我找到了this one, called hyperballs,它在Unity项目中成功用于分子可视化,称为UnityMol。我已经在项目中添加了OpenBabel dll,我希望我能以相同或任何其他方式为团结项目添加超球。

问题是我缺乏制作dll的经验(没有经验,说实话)。

此外,我不知道如何在Unity项目中使用超球c ++文件。 考虑与OpenBabel进行类比我认为如果有一种简单的方法可以在Mac上用c ++源代码创建一个dll,我可以简单地将dll添加到资源并享受编码,但它并不像我想象的那么容易。

1 个答案:

答案 0 :(得分:6)

您需要将C ++代码包装在C函数中,然后通过P / Invoke使用它们。

例如,

<强> MyPlugin.cpp

#define MY_API extern "C"

class Context
{
public:
    const int version = 12345;
};

MY_API int GetVersion(const Context* _pContext)
{
    if (_pContext == nullptr)
    {
        return 0;
    }
    return _pContext->version;
}

MY_API Context* CreateContext()
{
    return new Context();
}

MY_API void DestroyContext(const Context* _pContext)
{
    if (_pContext != nullptr)
    {
        delete _pContext;
    }
}

然后将上述代码编译为*.dll for Windows,*.so for Android,Cocoa Touch Static Library for iOS和bundle for macOS。

C#中的用法:

<强> MyPlugin.cs

using System;
using System.Runtime.InteropServices;
using UnityEngine;

public class MyAPI : MonoBehaviour
{
#if UNITY_EDITOR || UNITY_STANDALONE
    const string dllname = "MyPlugin";
#elif UNITY_IOS
    const string dllname = "__Internal";
#endif

    [DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
    private static extern IntPtr CreateContext();

    [DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
    private static extern int GetVersion(IntPtr _pContext);

    [DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
    private static extern void DestroyContext(IntPtr _pContext);

    static MyAPI()
    {
        Debug.Log("Plugin name: " + dllname);
    }

    void Start ()
    {
        var context = CreateContext();
        var version = GetVersion(context);
        Debug.LogFormat("Version: {0}", version);
        DestroyContext(context);
    }
}

参考文献:

  1. https://docs.unity3d.com/Manual/NativePlugins.html
  2. http://www.mono-project.com/docs/advanced/pinvoke/