Unity Native Plugin C#和C++互相调用

这篇具有很好参考价值的文章主要介绍了Unity Native Plugin C#和C++互相调用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

官方链接

1.DLL的方式:

C++代码:编译成DLL,导入Unity

#pragma once
#include <map>
#include <string>

//导出宏定义
#define _DllExport _declspec(dllexport)

//函数指针
typedef void (*NativeCallback)(const char*);

extern "C"
{
	//注意这里字符串不能用C++的std::string,和C#的string不等价,等价的是char*,即字符数组
	_DllExport void RegisterNativeCallback(const char* functionName, NativeCallback callback);
	_DllExport void UpdateNative();
}

//缓存C#函数的地址
std::map<std::string, NativeCallback> _callbackMap;

//导出让C#调用,注册C#端的函数,注册后就可以在C++端调用C#的函数,本质就职把C#函数的地址给到C++,C++调用。
_DllExport void RegisterNativeCallback(const char* functionName, NativeCallback callback)
{
	_callbackMap[std::string(functionName)] = callback;
}

//导出让C#调用
_DllExport void UpdateNative()
{
	//调用C#端的函数,可以在Unity性能分析界面看到Native update,用此方法可以在Unity界面查看C++代码的耗时
	_callbackMap[std::string("BeginSample")]("Native update");
	_callbackMap[std::string("Log")]("Native Log");
	_callbackMap[std::string("EndSample")]("Native update");
}

C#代码:

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

namespace Haha
{
    public class TestCPPLib : MonoBehaviour
    {
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        delegate void NativeCallback(string args);

        [DllImport("CPPLib")]
        static extern void RegisterNativeCallback(string functionName, IntPtr callback);

        [DllImport("CPPLib")]
        static extern void UpdateNative();

        [MonoPInvokeCallback(typeof(NativeCallback))]
        static void CallbackLog(string args)
        {
            Debug.Log(args);
        }

        [MonoPInvokeCallback(typeof(NativeCallback))]
        static void CallbackBeginSample(string args)
        {
            Profiler.BeginSample(args);
        }

        [MonoPInvokeCallback(typeof(NativeCallback))]
        static void CallbackEndSample(string args)
        {
            Profiler.EndSample();
        }

        void Start()
        {
        	//调用C++函数,注册C#函数
            RegisterNativeCallback("Log", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackLog)));
            RegisterNativeCallback("BeginSample", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackBeginSample)));
            RegisterNativeCallback("EndSample", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackEndSample)));
        }

        private void Update()
        {
        	//调用C++函数
            UpdateNative();
        }
    }
}

2.还有一种是C++源码作为插件,只支持il2cpp。

C++代码:直接放到Unity的Assets目录下

C#源文件:区别只在导入时不写具体的文件名,写:__Internal即可,因为用IL2CPP 后端的方式,会把C++源文件放到工程内部一块编译。

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

namespace Haha
{
    public class TestCPPLib : MonoBehaviour
    {
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        delegate void NativeCallback(string args);
		
		//区别在这里:
        [DllImport("__Internal")]
        static extern void RegisterNativeCallback(string functionName, IntPtr callback);

        [DllImport("__Internal")]
        static extern void UpdateNative();

        [MonoPInvokeCallback(typeof(NativeCallback))]
        static void CallbackLog(string args)
        {
            Debug.Log(args);
        }

        [MonoPInvokeCallback(typeof(NativeCallback))]
        static void CallbackBeginSample(string args)
        {
            Profiler.BeginSample(args);
        }

        [MonoPInvokeCallback(typeof(NativeCallback))]
        static void CallbackEndSample(string args)
        {
            Profiler.EndSample();
        }

        void Start()
        {
            RegisterNativeCallback("Log", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackLog)));
            RegisterNativeCallback("BeginSample", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackBeginSample)));
            RegisterNativeCallback("EndSample", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackEndSample)));
        }

        private void Update()
        {
            UpdateNative();
        }
    }
}

如果只是查看C++代码的耗时,unity提供了C++的接口,更加方便,视频最后有介绍。
Unity官方手册

//使用这两个原生接口,需要在C++项目属性配置:VC++目录->包含目录 或 C/C++->常规->附加包含目录,添加Unity这两个文件的文件路径
#include <IUnityInterface.h>
#include <IUnityProfiler.h>

static IUnityProfiler* s_UnityProfiler = NULL;
static const UnityProfilerMarkerDesc* s_MyPluginMarker = NULL;
static bool s_IsDevelopmentBuild = false;

extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces * unityInterfaces)
{
	s_UnityProfiler = unityInterfaces->Get<IUnityProfiler>();
	if (s_UnityProfiler == NULL)
		return;
	s_IsDevelopmentBuild = s_UnityProfiler->IsAvailable() != 0;
	s_UnityProfiler->CreateMarker(&s_MyPluginMarker, "MyCustomMethod", kUnityProfilerCategoryOther, kUnityProfilerMarkerFlagDefault, 0);
}

extern "C"  void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
	s_UnityProfiler = NULL;
}

extern "C" void UNITY_INTERFACE_EXPORT InterfaceUpdate()
{
	if (s_IsDevelopmentBuild)
	{
		s_UnityProfiler->BeginSample(s_MyPluginMarker);
	}

	//测试耗时代码
	for (int i = 0; i < 100000; i++)
	{

	}

	if (s_IsDevelopmentBuild)
	{
		s_UnityProfiler->EndSample(s_MyPluginMarker);
	}
}

关于IL2CPP打包的测试:
1.直接通过Unity构建,结构如下:如下:大小313M
Unity Native Plugin C#和C++互相调用,Unity,C++,c#,unity,c++
2.通过创建VS解决方案(可以在VS里设置断点,修改调试C++代码),在VS里构建,在构建界面设置:
Unity Native Plugin C#和C++互相调用,Unity,C++,c#,unity,c++
结构如下:bin目录包含软件的data目录,具体生成的exe在各自的平台下:
Unity Native Plugin C#和C++互相调用,Unity,C++,c#,unity,c++Unity Native Plugin C#和C++互相调用,Unity,C++,c#,unity,c++

Unity Native Plugin C#和C++互相调用,Unity,C++,c#,unity,c++
最终把bin目录的data文件夹和对应平台的exe何在一起,如下:大小162M
Unity Native Plugin C#和C++互相调用,Unity,C++,c#,unity,c++
上面的lib、pdb、exp可以删除,测试不影响运行,精简后的目录:大小50.8M
Unity Native Plugin C#和C++互相调用,Unity,C++,c#,unity,c++
结论:用vs构建的体积更小。文章来源地址https://www.toymoban.com/news/detail-524105.html

到了这里,关于Unity Native Plugin C#和C++互相调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity——在C#中调用C++动态链接库(DLL)

    1、新建C++空项目 打开VS,新建一个C++空项目,自命名项目名称与位置。 2、配置项目属性为动态链接库 右键项目,点击属性,打开项目属性页,将常规中的配置类型改为动态库(.dll)。  3、添加.h头文件 右键头文件,点击添加—新建项,选择头文件.h,命名为DllForUnity.h,点击

    2024年02月10日
    浏览(43)
  • ILRuntime是如何与Unity互相调用的

    一、ILRuntime的基本介绍 ILRuntime是一个跨平台CLR实现,它可以在多个平台上运行C#代码,包括Android、iOS、Windows、Linux等等。ILRuntime的实现方式是将C#代码编译成IL代码,然后在运行时通过JIT或AOT的方式将IL代码转换为机器代码,从而实现跨平台的效果。ILRuntime的主要功能包括热更

    2024年02月16日
    浏览(46)
  • 通过python在unity里调用C#接口

    log: 背景 最近在做虚拟人底层驱动sdk测试,因为后端使用的是C#,我个人更倾向于python编程辅助测试工作,测试sdk需要通过开发提供的接口方法文档,通过传测试场景参数调用方法进行单元测试 技术工具 项目语言 C# 项目工具 unity 测试语言 python3 实现过程 1.首先需要在unity安装

    2024年02月04日
    浏览(30)
  • Unity调用微软SpeechLib.Dll的C#类实现语音合成功能

    using System.Collections; using System.Collections.Generic; using UnityEngine; using SpeechLib; public class Speech : MonoBehaviour { // Start is called before the first frame update void Start() { } 将Interop.SpeechLib.dll文件导入Unity,然后把上面的脚本挂载到游戏对象上就能测试语音合成的效果了。 经测试 调用v.Speak这个方

    2024年02月13日
    浏览(52)
  • LabVIEW于C#各自生成的DLL互相调用的方法

    1.LV调用C#生成的DLL (1)C#类库代码原型 Debug生成的DLL: LV代码: 结果显示 2.C#调用LabVIEW生成的DLL: LV源码 VS2017添加LV生成的DLL 加入命名控件,加源码 运行结果:

    2024年02月16日
    浏览(61)
  • unity 调用C++ dll 操作升级套娃函数调用

    之前一直以为C++生成dll,在unity中调用时要把传出去的值设置在主函数中,以参数或反回值的形式。 当然在DLL工程中可以说没有主函数,那个可以运行一个函数,其会调用其他函数从而一直调其他相关函数。 那问题是在层级是二或三------时被调用的那个函数的计算结果怎么能

    2024年02月13日
    浏览(38)
  • unity 调用C++ dll 有类和指针操作

    这个在之前unity 调用C++ dll 操作升级套娃函数调用_天人合一peng的博客-CSDN博客的基础上,但实事时类相互嵌套,非常不好处理。 1 测试直接将main()生成dll程序能运行不。  发现是可以的。 2 那就是想方法把对象或指针的操作的下一级函数直接写到main里面,不就可以可以了吗。

    2024年02月16日
    浏览(35)
  • 【100个 Unity实用技能】☀️ | 关于触发器互相检测的必要前提条件配置

    老规矩,先介绍一下 Unity 的科普小知识: Unity 是 实时3D互动内容创作和运营平台 。 包括 游戏开发 、 美术 、 建筑 、 汽车设计 、 影视 在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和

    2023年04月09日
    浏览(71)
  • 【游戏开发算法每日一记】使用随机prime算法生成错综复杂效果的迷宫(C#,C++和Unity版)

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity基础实战 1.首先全部判定为墙,最外的为路包裹墙( 类似于防止数组越界 ) 2.红色为它的检测范围(假设检测点在如图所示的位置)—

    2024年02月05日
    浏览(41)
  • 【Unity】【VR开发疑难】Unity运行就报无法启动XR Plugin

    连接Link后运行Unity的VR项目Link也无反映,Unity控制台报:无法启动XR Plugin,并说是由于Oculus头盔未连接导致。 打开Oculus PC客户端,发现状态是连接正常。重启机器后,提示Oculus没有出于RunTime。 想到刚才升级过客户端,可能就是因为升级后某些设置归位了,导致连接不被Unit

    2024年02月06日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包