让Unity可以释放DllImport的引用的dll

语法

在Unity使用DllImport,导入C++写的dll后,如果Unity Editor停止运行,导入的dll还被引用住,如果要修改dll,就必须关闭Unity,导致了调试很耗时。

追踪DllImport的代码,可以发现,对应函数在第一次调用时,走到mono的函数如下:

graph TD
    A[mono_lookup_pinvoke_call] --> B[cached_module_]
    B --> C[cached_module_load]
    C --> D[mono_dl_open]
    D -->E[LoadLibrary]

本质上就是调用Windows的LoadLibrary加载dll,然后调用GetProcAddress(函数名)获取对应函数的地址。理论上讲使用FreeLibrary(hmodule)可以把dll释放掉。为了验证想法,单独作了下小测试:

// 新建一个MathDll工程,并生成dll,代码如下:

extern "C"
{
  __declspec(dllexport) int DoAdd(int a, int b)
  {
    return a + b;
  }
}

// 再新建一个DllLoadUnload win32 console工程,代码如下:

#include 
#include 

extern "C"
{
  typedef int (func)(int, int);
}

int main()
{
  while (1)
  {
    HMODULE hmodule = ::LoadLibrary("MathDll.dll");
    func* add = (func*)::GetProcAddress(hmodule, "DoAdd");
    std::cout << "add result = " << (*add)(1, 2) << std::endl;
    ::FreeLibrary(hmodule);
    system("pause");
  }
  return 0;
}

// 代码结束

在system("pause")时,先不要结束程序,会发现MathDll.dll可以删除。

把FreeLibrary注释掉,再编译一次,会发现在system("pause")时,删除MathDll.dll会提示dll被占用。

因此,验证通过,可以使用FreeLibrary来释放引用住的dll。

所以,可以mono加个接口,释放指定名字的dll,然后在Unity中加个接口来调用就可以,完。

你可能感兴趣的:(让Unity可以释放DllImport的引用的dll)