2017-05-02 20 views
7

在Unity中製作C++插件時,使用Debug.Log可以更容易地快速查看變量值,但此功能僅可從C#端獲得。這使得調試C++插件非常困難,因爲Unity的調試器不支持該插件。 std::cout不是一個選項,因爲它沒有在編輯器中顯示。使用來自C++的Debug.Log

我查看了位於<UnityInstallationDirecory>\Editor\Data\PluginAPI的Unity C++ API,但沒有發現任何有關登錄API的信息。

關於如何在C編輯器中顯示日誌的任何建議?

+1

是否正在爲您調用一個選項? http://answers.unity3d.com/questions/30620/how-to-debug-c-dll-code.html – Smartis

+1

@Smartis謝謝。這看起來很有前途,但由於AOT,它不適用於iOS。這是一個好的開始。我會發布適用於iOS的答案,如果我得到它的工作。 – Programmer

回答

5

這可以通過回調函數完成。發送一個指向一個函數的指針,從C#到C++將它存儲在一個臨時變量中。將Debug.Log放入該回調函數中,並允許它作爲指針接收字符串(IntPtr)。

當從C++調用此函數時,請將IntPtr轉換爲帶有Marshal.PtrToStringAnsi的字符串。

要使其在iOS上工作,您必須在回調函數中使用MonoPInvokeCallback屬性。

C#(附加到一個空的遊戲物體):

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

public class DebugCPP : MonoBehaviour 
{ 

    // Use this for initialization 
    void OnEnable() 
    { 
     RegisterDebugCallback(OnDebugCallback); 
    } 

    //------------------------------------------------------------------------------------------------ 
    [DllImport("DebugLogPlugin", CallingConvention = CallingConvention.Cdecl)] 
    static extern void RegisterDebugCallback(debugCallback cb); 
    //Create string param callback delegate 
    delegate void debugCallback(IntPtr request, int color, int size); 
    enum Color { red, green, blue, black, white, yellow, orange }; 
    [MonoPInvokeCallback(typeof(debugCallback))] 
    static void OnDebugCallback(IntPtr request, int color, int size) 
    { 
     //Ptr to string 
     string debug_string = Marshal.PtrToStringAnsi(request, size); 

     //Add Specified Color 
     debug_string = 
      String.Format("{0}{1}{2}{3}{4}", 
      "<color=", 
      ((Color)color).ToString(), 
      ">", 
      debug_string, 
      "</color>" 
      ); 

     UnityEngine.Debug.Log(debug_string); 
    } 
} 

C++DebugCPP.h):

#pragma once 
#include<stdio.h> 
#include <string> 
#include <stdio.h> 
#include <sstream> 

#define DLLExport __declspec(dllexport) 

extern "C" 
{ 
    //Create a callback delegate 
    typedef void(*FuncCallBack)(const char* message, int color, int size); 
    static FuncCallBack callbackInstance = nullptr; 
    DLLExport void RegisterDebugCallback(FuncCallBack cb); 
} 

//Color Enum 
enum class Color { Red, Green, Blue, Black, White, Yellow, Orange }; 

class Debug 
{ 
public: 
    static void Log(const char* message, Color color = Color::Black); 
    static void Log(const std::string message, Color color = Color::Black); 
    static void Log(const int message, Color color = Color::Black); 
    static void Log(const char message, Color color = Color::Black); 
    static void Log(const float message, Color color = Color::Black); 
    static void Log(const double message, Color color = Color::Black); 
    static void Log(const bool message, Color color = Color::Black); 

private: 
    static void send_log(const std::stringstream &ss, const Color &color); 
}; 

C++DebugCPP.cpp):

#include "DebugCPP.h" 

#include<stdio.h> 
#include <string> 
#include <stdio.h> 
#include <sstream> 

//------------------------------------------------------------------- 
void Debug::Log(const char* message, Color color) { 
    if (callbackInstance != nullptr) 
     callbackInstance(message, (int)color, (int)strlen(message)); 
} 

void Debug::Log(const std::string message, Color color) { 
    const char* tmsg = message.c_str(); 
    if (callbackInstance != nullptr) 
     callbackInstance(tmsg, (int)color, (int)strlen(tmsg)); 
} 

void Debug::Log(const int message, Color color) { 
    std::stringstream ss; 
    ss << message; 
    send_log(ss, color); 
} 

void Debug::Log(const char message, Color color) { 
    std::stringstream ss; 
    ss << message; 
    send_log(ss, color); 
} 

void Debug::Log(const float message, Color color) { 
    std::stringstream ss; 
    ss << message; 
    send_log(ss, color); 
} 

void Debug::Log(const double message, Color color) { 
    std::stringstream ss; 
    ss << message; 
    send_log(ss, color); 
} 

void Debug::Log(const bool message, Color color) { 
    std::stringstream ss; 
    if (message) 
     ss << "true"; 
    else 
     ss << "false"; 

    send_log(ss, color); 
} 

void Debug::send_log(const std::stringstream &ss, const Color &color) { 
    const std::string tmp = ss.str(); 
    const char* tmsg = tmp.c_str(); 
    if (callbackInstance != nullptr) 
     callbackInstance(tmsg, (int)color, (int)strlen(tmsg)); 
} 
//------------------------------------------------------------------- 

//Create a callback delegate 
void RegisterDebugCallback(FuncCallBack cb) { 
    callbackInstance = cb; 
} 

從C++用途:從所述編輯器

Debug::Log("Hellow Red", Color::Red); 
Debug::Log("Hellow Green", Color::Green); 
Debug::Log("Hellow Blue", Color::Blue); 
Debug::Log("Hellow Black", Color::Black); 
Debug::Log("Hellow White", Color::White); 
Debug::Log("Hellow Yellow", Color::Yellow); 
Debug::Log("Hellow Orange", Color::Orange); 

Debug::Log(true, Color::Black); 
Debug::Log(false, Color::Red); 

輸出:

enter image description here

現在,您可以輕鬆實施Debug.LogWarningDebug.LogError

+3

當然,甚至顏色!好的特點。謝謝 – Smartis

+3

顏色對於輕鬆分離不同日誌非常有用。不用謝! – Programmer