调用C# DLL接口
一、用Visual Studio生成一个dll
因为unity只支持.NET Framework 2.0,所以生成dll时一定要设置成使用.NET Framework 2.0
如果.NET版本过高,unity会报以下错:
Internal compiler error. See the console log for more information. output was:
Unhandled Exception: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (bool)
at System.Reflection.Assembly.GetTypes () [0x00000] in <filename unknown>:0
at Mono.CSharp.RootNamespace.ComputeNamespaces (System.Reflection.Assembly assembly, System.Type extensionType) [0x00000] in <filename unknown>:0
at Mono.CSharp.RootNamespace.ComputeNamespace (Mono.CSharp.CompilerContext ctx, System.Type extensionType) [0x00000] in <filename unknown>:0
at Mono.CSharp.GlobalRootNamespace.ComputeNamespaces (Mono.CSharp.CompilerContext ctx) [0x00000] in <filename unknown>:0
at Mono.CSharp.Driver.LoadReferences () [0x00000] in <filename unknown>:0
at Mono.CSharp.Driver.Compile () [0x00000] in <filename unknown>:0
at Mono.CSharp.Driver.Main (System.String[] args) [0x00000] in <filename unknown>:0
示例:
1. 创建dll
using System; namespace DllTest { public class DllClassTest { public string GetValue() { return "This is DllTest"; } } }
2. 把dll放在Assets/下面
3. 在unity中调用dll
using UnityEngine; using DllTest; public class Test : MonoBehaviour { void Start () { //测试调用dll DllClassTest obj = new DllClassTest(); string str = obj.GetValue(); Debug.Log(str); } }
运行效果
示例二
一、Visual Studio创建类库
二、引用Unity安装目录下的UnityEditor.dll、UnityEngine.dll
三、创建类
using System; using System.Collections.Generic; using UnityEngine; public class Class1 : MonoBehaviour { public string id; void Awake() { Debug.Log("Awake()"); } void OnEnable() { Debug.Log("OnEnable()"); } void OnDisable() { Debug.Log("OnDisable()"); } void OnDestroy() { Debug.Log("OnDestroy()"); } }
四、生成dll文件并拷到Unity工程下
五、Unity工程中使用生成的dll文件
运行效果
动态加载dll
一、将示例二中的dll改名为SGZS.bytes并打包成SGZS.assetbundle
二、测试动态加载dll
using UnityEngine; using System; using System.Collections; using System.Reflection; public class Test : MonoBehaviour { void Start () { StartCoroutine(LoadWWWDLL()); } IEnumerator LoadWWWDLL() { yield return null; //为了方便测试暂时放在本地加载,实际使用时放到web服务器上。 string url = "file:///" + Application.persistentDataPath + "/SGZS.assetbundle"; Debug.Log("url=" + url); //加载dll WWW www = new WWW(url); yield return www; //提取dll AssetBundle bundle = www.assetBundle; TextAsset asset = bundle.Load("SGZS", typeof(TextAsset)) as TextAsset; //载入程序集 Assembly ass = Assembly.Load(asset.bytes); Debug.Log("Assembly:" + ass); //创建GameObject并挂上脚本Class1 Type type1 = ass.GetType("Class1"); GameObject go = new GameObject("Class1"); go.AddComponent(type1); } }
运行效果
调用C/C++接口
CTestDll.h
#ifndef __CTEST_DLL_H #define __CTEST_DLL_H // 声明为C编译、链接方式为外部函数 extern "C" _declspec(dllexport) int _cdecl add(int* x, int* y); extern "C" _declspec(dllexport) int _cdecl sub(int x, int y); #endif
CTestDll.cpp
#include "CTestDll.h" #ifdef __cplusplus //如果是cpp文件 extern "C" //这部分代码按C编译 { int add(int* x, int* y) { return *x + *y; } int sub(int x, int y) { return x - y; } } #endif
Unity工程
using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using UnityEngine; public class DllWrap : MonoBehaviour { //.dll后缀可以不用写 [DllImport(@"Dll4.dll", EntryPoint = "add", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] public static extern int add(ref int x, ref int y); [DllImport(@"Dll4.dll", EntryPoint = "sub", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] public static extern int sub(int x, int y); void Start() { int x = 6, y = 5; int a = add(ref x, ref y); int b = sub(x, y); Debug.LogFormat("a={0}, b={1}", a, b); } }
运行测试