在unity中我使用了c#的系统函数,System.Threading.Mutex 这个函数
在Windows上进行跨进程通信,需要读取一个互斥量,观察unity运行的TCP服务器有没有正常启动
这时使用IL2CPP的方式进行编译发布,发现运行时在如下行出现异常:
mutex = new System.Threading.Mutex(true, "test_mutex", out have);
使用try,catch捕获异常,显示函数调用异常,也就是找不到函数的实现。
通过查看IL2CPP编译之后的C++源码发现,函数实现出现问题,并未转换成功
具体代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestMutex : MonoBehaviour
{
// Start is called before the first frame update
System.Threading.Mutex mutex;
void Start()
{
CreateMutex();
ReleaseMutex();
CloseMutex();
}
// 创建互斥量
public void CreateMutex()
{
bool have = false;
mutex = new System.Threading.Mutex(true, "test_mutex", out have);
}
// 释放互斥量
public void ReleaseMutex()
{
mutex.ReleaseMutex();
}
// 释放资源
public void CloseMutex()
{
mutex.Close();
}
}
二、解决方案
使用system.threading.mutex默认的库,既然存在问题,
而我们需要解决的问题是使用互斥量进行进程通信
所以我们可以使用windows自带的mutex API
在Windows中有四个API
CreateMutex();
OptenMutex();
RelaseMutex();
CloseHandle();
原型如下:
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateMutexW(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCWSTR lpName
);
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
OpenMutexA(
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ LPCSTR lpName
);
WINBASEAPI
BOOL
WINAPI
ReleaseMutex(
_In_ HANDLE hMutex
);
WINBASEAPI
BOOL
WINAPI
CloseHandle(
_In_ _Post_ptr_invalid_ HANDLE hObject
);
所以只要在unity中引入上述DLL,同时进行使用上述API,就能够达成我们所需要的目的
C#使用引入windowsAPI的流程如下:
1、 确定WindowsAPI所在DLL
2、重新定义函数的原型
3、在C#中调用对应函数
例子如下:
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
public static class Import
{
[DllImport("kernel32.dll")]
public static extern System.IntPtr CreateMutexW(
System.IntPtr lpMutexAttributes,
bool bInitialOwner,
string lpName
);
[DllImport("kernel32.dll")]
public static extern bool ReleaseMutex(System.IntPtr hMutex);
[DllImport("kernel32.dll")]
public static extern bool CloseHendle(System.IntPtr hObject);
}
public class TestMutex : MonoBehaviour
{
// Start is called before the first frame update
System.IntPtr mutex;
void Start()
{
CreateMutex();
ReleaseMutex();
CloseMutex();
}
// 创建互斥量
public void CreateMutex()
{
mutex = Import.CreateMutexW(System.IntPtr.Zero, true, "testMutex");
}
// 释放互斥量
public void ReleaseMutex()
{
Import.ReleaseMutex(mutex);
}
// 释放资源
public void CloseMutex()
{
Import.CloseHendle(mutex);
}
}
通过DllImport操作引入动态库,需要添加 using System.Runtime.InteropServices;
把函数原型中 指针 转换为 System.IntPtr;
把函数原型中 字符串 转换为 String
把函数原型中BOOL 转换为 bool
就能够实现函数的快速调用了