IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity显示C++动态库中的Log -> 正文阅读

[游戏开发]Unity显示C++动态库中的Log

引子

需求是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

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-12-26 22:33:05  更:2021-12-26 22:34:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 21:05:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码