Unity显示C++动态库中的Log

6 篇文章 0 订阅

引子

需求是Unity的项目调用C++动态库的逻辑,并进行调试,这时就需要能够通过Log,观测C++动态库中的逻辑是否正常运行。
这个需求的底层逻辑其实就是,在C++中做一个“信息发送器”,C#中有一个“接收器”。在Log信息时,就是C++将Log内容,发送给C#,从而在Unity中显示出来。
该文章中的代码经过实际项目检测,可以直接使用。

C++部分

直接上代码:

头文件UnityDebug.hpp

#ifndef UnityDebug_hpp
#define UnityDebug_hpp

#include <stdio.h>
#include "string.h"
#define UnityLog(acStr, ...) Debug::L(acStr, ##__VA_ARGS__);

//C++ Call C#
class Debug
{
    public:
    static void (*Log)(char* message, int iSize);
    static void L(const char* msg, ...);
};

extern "C" void InitCSharpDelegate(void (*Log)(char* message, int iSize));

#endif /* UnityDebug_hpp */

源文件UnityDebug.cpp

#include <stdarg.h>
#include "UnityDebug.hpp"

void (*Debug::Log)(char* message, int iSize);
void Debug::L(const char* fmt, ...)
{
    if(Debug::Log == NULL)return;
    char acLogStr[512];// = { 0 };
    va_list ap;
    va_start(ap, fmt);
    vsprintf(acLogStr, fmt, ap);
    va_end(ap);
    Debug::Log(acLogStr, strlen(acLogStr));
}

void InitCSharpDelegate(void(*Log)(char* message, int iSize))
{
    Debug::Log = Log;
    UnityLog("Cpp Message:Log has initialized");
}

C++中的使用

创建完以上两个文件后,在需要Log的地方,调用UnityLog("*****");即可。具体用法与printd()函数一样。

Unity的C#代码

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

public class DllLog
{
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void LogDelegate(IntPtr message, int iSize);
    [DllImport("macVTA", CallingConvention = CallingConvention.Cdecl)]
    public static extern void InitCSharpDelegate(LogDelegate log);
    //C# Function for C++‘s call
    [MonoPInvokeCallback(typeof(LogDelegate))]
    public static void LogMessageFromCpp(IntPtr message, int iSize)
    {
        Debug.Log(Marshal.PtrToStringAnsi(message, iSize));
    }
    public static void ShowLog()
    {
        InitCSharpDelegate(LogMessageFromCpp);
    }
}

Unity端的使用

在程序运行的一开始调用一次ShowLog();即可,这样C++中的所有Log都会在相应的程序位置显示在Unity控制台中。

逻辑原理

将C++与C#的代码都写好,并测试成功后,再来对照着看一下其中的逻辑原理。

  • 首先,在C++中调用的UnityLog("*****");,通过头文件(UnityDebug.hpp)可以知道,它其实就是类DebugL函数(Debug::L);
  • 该函数方法的实现,就是将参数进行了一些转换/合并,最后传入了函数指针Debug::Log
  • 而函数指针Debug::Log,则是在经过关键字extern "C"声明后的外部函数方法void InitCSharpDelegate(void (*Log)(char* message, int iSize));的实现中进行了“赋值”;
  • InitCSharpDelegate作为外部方法,对应了C#代码中被声明的public static extern void InitCSharpDelegate(LogDelegate log);,其中的参数LogDelegate,则是对应了C++代码中的static void (*Log)(char* message, int iSize);函数指针的public delegate void LogDelegate(IntPtr message, int iSize);委托;
  • Unity的C#代码调用的ShowLog();,就是将函数LogMessageFromCpp作为委托(或函数指针)传入了外部方法(extern关键字)InitCSharpDelegate中;
  • 这样在C++程序调用UnityLog方法时,其实就是将信息进行转化/合并后,传入了委托/函数指针LogMessageFromCpp中,从而显示在了Unity控制台上。

参考链接

https://blog.csdn.net/heima201907/article/details/106349104

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天富儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值