2017-05-02 32 views
7

Unity içinde C++ eklentileri yaparken, değişken değerleri hızlı bir şekilde görüntülemek için Debug.Log'u kullanmak daha kolaydır, ancak bu işlev yalnızca C# tarafından kullanılabilir. Bu, Unity'nin hata ayıklayıcısını desteklemediğinden C++ eklentisinin hata ayıklanmasını çok zorlaştırır. Editör'de gösterilmediği için std::cout bir seçenek değildir.C++ 'dan Debug.Log kullanın

<UnityInstallationDirecory>\Editor\Data\PluginAPI'da bulunan Unity C++ API'sine baktım ancak API'da oturum açma hakkında hiçbir şey bulamadım.

Editör günlüğünde C++ 'dan nasıl görüntüleneceğine dair herhangi bir öneriniz var mı?

+1

Ters sizin için bir seçenek mi çağırıyor? http://answers.unity3d.com/questions/30620/how-to-debug-c-dll-code.html – Smartis

+1

@Smartis Teşekkürler. Bu umut verici görünüyor ancak AOT nedeniyle iOS'ta çalışmayacak. Bu iyi bir başlangıç. Çalışırsam da iOS üzerinde çalışan bir cevap yayınlayacağım. – Programmer

cevap

5

Bu, geri arama işleviyle yapılabilir. Bir işleve bir işaretçiyi C# ile C++ arasında geçici bir değişkende saklayın. Geri arama işlevinin içine Debug.Log girin ve işaretçi olarak dizeleri almasına izin verin (IntPtr).

Bu işlev C++ 'den çağrıldığında, IntPtr değerini Marshal.PtrToStringAnsi ile dizeye dönüştürün.

iOS'ta çalışmasını sağlamak için geri arama işlevindeki MonoPInvokeCallback özniteliğini kullanmanız gerekir.

C# (boş GameObject tutunur):

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): C++ den

#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; 
} 

Kullanım: Editör den

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); 

Çıkış:

enter image description here

Artık Debug.LogWarning ve Debug.LogError'u kolayca uygulayabilirsiniz.

+3

dang, hatta Renkler! Güzel Özellik. Teşekkürler – Smartis

+3

Renk, farklı günlükleri kolayca ayırmak için gerçekten yararlıdır. Rica ederim! – Programmer