[英]Build C++ plugin for Unity
嘗試創建我的第一個插件。 cpp代碼為:
標頭:
#pragma once
#ifndef __MY_DLL_H
#define __MY_DLL_H
extern "C" int add_1(int number);
#endif
資源:
//FirstDLL.cpp
#include "FirstDLL.h"
extern "C" int add_1(int number) {
return number + 1;
}
然后我編譯該DLL並將其放在Assets/Plugins
文件夾中,該dll文件是FirstDLL.dll
。 從統一的角度來看,我為組件提供了一個簡單的C#腳本:
using UnityEngine;
public class MyBehaviour : MonoBehaviour {
// Use this for initialization
[Header("Nuts!")]
public int my_curr_val;
void Start () {
}
// Update is called once per frame
void Update () {
print(add_1(my_curr_val));
}
[DllImport("FirstDLL")]
public static extern int add_1(int number);
}
但是,當我嘗試運行腳本時,出現以下錯誤:
插件:未能加載錯誤“此操作僅在應用程序容器的上下文中有效”的“ Assets / Plugins / FirstDLL.dll”。 '。 插件:未能加載錯誤“此操作僅在應用程序容器的上下文中有效”的“ Assets / Plugins / FirstDLL.dll”。 '。 DllNotFoundException:FirstDLL MyBehaviour.Update()(位於Assets / MyBehaviour.cs:17)
文檔似乎很差,有什么建議嗎? 有這個答案 ,但不確定我在做什么錯。 我試圖創建幾種解決方案(Windows通用平台,Windows 8.1等)仍然無法正常工作。
您正在嘗試在非UWP環境中加載UWP插件,這是由於生成dll的方式所致。
這篇文章介紹了如何在Unity中創建,編譯和構建C ++插件。
用於此目的的軟件版本(也應適用於其他較舊的版本。僅在將來有更新和不同的UI時提及此信息):
Microsoft Visual Studio 2015
Unity 2017.2.0f3
1。轉到文件 ---> 新建 ---> 項目...
2 。 轉到已安裝 -> 模板 ---> Visual C ++,然后轉到Win32控制台應用程序 。 輸入項目的名稱,然后單擊“確定”。
3。單擊下一步而不是完成 :
4。選擇DLL並取消選擇Precompiled標頭,然后單擊完成:
5。您現在可以創建源文件(.cpp)和頭文件(.h)。
一個。創建源文件:
這應該放在“ 源文件”文件夾中。 右鍵單擊源文件--->添加--->新建項目...
B。選擇 C ++ File(.cpp),鍵入文件“ FirstDLL.cpp”的名稱,然后單擊“添加”。
示例C ++測試源:
#include "FirstDLL.h"
int add(int num1, int num2)
{
return num1 + num2;
}
int multiply(int num1, int num2)
{
return num1 * num2;
}
int substract(int num1, int num2)
{
return num1 - num2;
}
int divide(int num1, int num2)
{
return num1 / num2;
}
一個。創建頭文件:
應將其放置在“ 頭文件”文件夾中。 右鍵單擊頭文件--->添加--->新建項目...
B。選擇 Header File(.h) ,輸入文件“ FirstDLL.h”的名稱,然后單擊Add。
相應的標題示例:
#ifndef FIRSTDLL_NATIVE_LIB_H
#define FIRSTDLL_NATIVE_LIB_H
#define DLLExport __declspec(dllexport)
extern "C"
{
DLLExport int add(int num1, int num2);
DLLExport int multiply(int num1, int num2);
DLLExport int substract(int num1, int num2);
DLLExport int divide(int num1, int num2);
}
#endif
而已。 您現在可以在此處編寫C ++插件代碼。
6。確保將構建版本設置為release,平台設置為64位
如果使用32位,則將平台設置為x86。
7 。 建築插件:
轉到構建 ---> 構建解決方案
8 。 導入Unity:
PC,Mac和Linux獨立版 :
將64位dll文件放入Assets/Plugins
文件夾中。
如果只想支持32位,則將插件放在Assets/Plugins/x86
。
如果要支持通用(32位和64位平台),則應以這種方式構建dll,並將其放在Assets/Plugins/x86_64
文件夾中。
安卓 :
可以從Android Studio構建。
要從Visual Studio生成:
一 。去文件 - > 新建 - > 項目...
B. 轉到已安裝 -> 模板 ---> Visual C ++,然后跨平台 。 單擊安裝Android對C ++的支持(更新x) 。 然后按照說明進行安裝。
C. 轉到已安裝 -> 模板 ---> Visual C ++ ---> 跨平台 。 然后是Android 。 選擇“ 動態碎片庫(Android)”,然后輸入項目名稱,然后單擊“確定”。 現在,您可以跳回到步驟5,以繼續使用C ++進行編碼。
將Android插件文件(不是dll)放入Assets/Plugins/Android
文件夾中。 受支持的C ++插件擴展.so
。
注意 :如果Android插件的名稱是libFirstDLL-lib.so
,請從C#中引用它時,刪除lib
前綴和.so
。在這種情況下,與[DllImport("FirstDLL-lib")]
不同本來應該是#9。
如果您同時擁有armeabi-v7a
和x86
Android .so
插件,則分別將它們分別放在Assets\\Plugins\\Android\\libs\\armeabi-v7a
和Assets\\Plugins\\Android\\libs\\x86
文件夾中。
的iOS
可以從Xcode構建或將源文件包含到Unity中。 您也可以使用visual Studio創建它。 只需按照上述Android步驟操作,但這次使用“ 安裝iOS對C ++的支持(更新x)”,而不是“ 安裝Android對C ++的支持(更新x)” 。 請注意,您需要Mac計算機才能為iOS構建或使用虛擬機。 一旦你這樣做,請按照這個微軟提示完成設置,使Visual Studio可以溝通和建立在你的Mac OS項目。
將iOS插件文件(不是dll)放入Assets/Plugins/iOS
文件夾中。 支持的插件擴展名是.a
, .m
, .mm
, .c
, .cpp
。
必須使用[DllImport ("__Internal")]
代替[DllImport("PluginName")]
或[DllImport("FirstDLL")]
如下面的#9所示 。
9 。 從Unity / C#調用C ++函數 :
[DllImport("FirstDLL")]
public static extern int add(int num1, int num2);
[DllImport("FirstDLL")]
public static extern int multiply(int num1, int num2);
[DllImport("FirstDLL")]
public static extern int substract(int num1, int num2);
[DllImport("FirstDLL")]
public static extern int divide(int num1, int num2);
void Start()
{
Debug.Log("Add: " + add(10, 2));
Debug.Log("Multiply: " + multiply(10, 2));
Debug.Log("Substract: " + substract(10, 2));
Debug.Log("Divide: " + divide(10, 2));
}
輸出 :
10 。 故障排除插件錯誤:
1。得到錯誤:
DllNotFoundException:
解決方案1 :
DllImport
中指定的DLL的名稱與Dll名稱不匹配。 通過重命名它們來確保它們匹配,然后重新啟動Unity。
解決方案2 :
DLL放在錯誤的文件夾中。 該文件夾必須命名為Assets/Plugins
。 拼寫也區分大小寫。
2。得到錯誤:
EntryPointNotFoundException:
解決方案1 :
聲明為DllImport
的函數名不存在或與C ++側聲明的函數名匹配。 確保雙方的拼寫相同。 拼寫也區分大小寫。
解決方案2 :
C ++ DLL函數未包含在C ++插件中。 在Windows上, dllexport
用於使這些函數自己在DLL中導出。 在其他平台或操作系統中,這不是必需的。 通常在頭文件中執行此操作只是為了保持源文件的干凈。 請參見上方頭文件中的示例或下方屏幕截圖。
解決方案3 :
您的編譯器正在重命名C ++函數。 您可以通過使用extern
關鍵字將其括起來來防止這種情況。 同樣,請參見上方頭文件中的示例或下方屏幕截圖:
2。沒有錯誤,但結果不正確或連線錯誤:
解決方案1 :
參數不匹配。 確保C ++和C#端的函數參數匹配,並且具有相同數量的參數。 數據類型也必須匹配。 如果不這樣做,請期待未定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.