淄博周村網(wǎng)站建設(shè)哪家好杭州網(wǎng)絡(luò)推廣
上一篇文章中我使用UnrealSharp成功使用了我的一個C#控制臺程序中的網(wǎng)絡(luò)模塊,這個程序是基于KCP網(wǎng)絡(luò)了,其中調(diào)用了Cmake 編譯的一個C++的DLL,在虛幻中DLL需要放在Binaries目錄中才可以。Unity中只要放在任意Plugins目錄中就可以。
但是Binaries目錄版本控制一般不提交,我們可以改一下,改成按照路徑加載。
修改前的腳本
using System.Runtime.InteropServices;//腳本修改自//https://github.com/a11s/kcp_warppernamespace NetLibrary
{public unsafe class KCP{const string LIBNAME = "libikcp.dll";//---------------------------------------------------------------------// interface//---------------------------------------------------------------------/// <summary>/// create a new kcp control object, 'conv' must equal in two endpoint/// from the same connection. 'user' will be passed to the output callback/// output callback can be setup like this: 'kcp->output = my_udp_output'/// </summary>/// <param name="conv"></param>/// <param name="user"></param>/// <returns></returns>[DllImport(LIBNAME, EntryPoint = "ikcp_create", CallingConvention = CallingConvention.Cdecl)]public static extern IKCPCB* ikcp_create(uint conv, void* user);/// <summary>/// release kcp control object/// </summary>/// <param name="kcp"></param>[DllImport(LIBNAME, EntryPoint = "ikcp_release", CallingConvention = CallingConvention.Cdecl)]public static extern void ikcp_release(IKCPCB* kcp);/// <summary>/// set output callback, which will be invoked by kcp///public static extern void ikcp_setoutput(IKCPCB* kcp, int (* output)(byte* buf, int len, ikcpcb *kcp, void* user));/// </summary>/// <param name="kcp"></param>/// <param name="d_output"></param>[DllImport(LIBNAME, EntryPoint = "ikcp_setoutput", CallingConvention = CallingConvention.Cdecl)]public static extern void ikcp_setoutput(IKCPCB* kcp, System.IntPtr d_output);
篇幅太大沒有必要,只展示部分代碼片段。
可以看到之前是通過DllImport 載入LIBNAME變量來載入DLL的。
改為動態(tài)路徑
先放上所有改動
// 動態(tài)獲取庫路徑
private static string GetLibraryPath()
{string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;//動態(tài)庫的路徑被拼接到 Binaries\Managed\Third\libikcp.dll,而你的實際庫文件存放在 E:\myproject\Third\libikcp.dll,這說明 AppDomain.CurrentDomain.BaseDirectory 返回的路徑是 Binaries\Managed。baseDirectory = Path.Combine(baseDirectory, "../../");string relativePath;// 根據(jù)平臺選擇庫路徑if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)){relativePath = "ThirdParty/Kcp/Win64/libikcp.dll";}else if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID"))){relativePath = "ThirdParty/Kcp/Android/arm64-v8a/libikcp.so";}else{throw new PlatformNotSupportedException("Unsupported platform");}return Path.Combine(baseDirectory, relativePath);
}// DllImport 使用動態(tài)路徑
private const string LIBNAME = "PLACEHOLDER"; // 占位符
private static bool _isResolverSet = false;
// 添加初始化方法以動態(tài)設(shè)置路徑
public static void Initialize()
{if (_isResolverSet){Loger.Debug($"BSserver DLL: 已經(jīng)加載過了 .");return;}try{string libraryPath = GetLibraryPath();//Loger.Error($"BSserver DLL:{libraryPath}");NativeLibrary.SetDllImportResolver(typeof(KCP).Assembly, (name, assembly, path) =>{if (name == LIBNAME){return NativeLibrary.Load(libraryPath);}return IntPtr.Zero;});_isResolverSet = true;}catch(Exception e) {//AClientMain.inst.PrintString("C# : DLL:" + libraryPath);Console.WriteLine($"Loaded library 加載錯誤 ."+e.Message);Loger.Error($"BSserver DLL 加載錯誤 : " + e.Message);}}
//const string LIBNAME = "libikcp.dll";
//---------------------------------------------------------------------
// interface
//---------------------------------------------------------------------/// <summary>
/// create a new kcp control object, 'conv' must equal in two endpoint
/// from the same connection. 'user' will be passed to the output callback
/// output callback can be setup like this: 'kcp->output = my_udp_output'
/// </summary>
/// <param name="conv"></param>
/// <param name="user"></param>
/// <returns></returns>
[DllImport(LIBNAME, EntryPoint = "ikcp_create", CallingConvention = CallingConvention.Cdecl)]
public static extern IKCPCB* ikcp_create(uint conv, void* user);/// <summary>
/// release kcp control object
/// </summary>
/// <param name="kcp"></param>
[DllImport(LIBNAME, EntryPoint = "ikcp_release", CallingConvention = CallingConvention.Cdecl)]
public static extern void ikcp_release(IKCPCB* kcp);
使用方法:
我們在UE的工程下創(chuàng)建目錄ThirdParty,按照代碼里的路徑,把DLL放進去,按照不同平臺。
在加載DLL之前,我們需要調(diào)用Initialize方法初始化動態(tài)設(shè)置路徑就可以了。
這些代碼是ChatGPT幫忙寫的,經(jīng)過幾次修改有了這段代碼。
小技巧
以前是內(nèi)事不決問baidu,外事不決問google,現(xiàn)在是內(nèi)事問豆包,外事問ChatGPT。 :)
但是小心AI一本正經(jīng)的胡說八道。 :P