我有一个C#程序,它使用LoadLibrary加载一个非托管C ++ DLL,然后用FreeLibrary卸载它。应用程序运行正常,我可以在C#应用程序中随意加载,卸载和文件级替换DLL。
对于某些(新的)原因,现在当我使用FreeLibrary DLL时,它成功地从C#卸载(我从FreeLibrary获得正值返回值),但* .dll文件仍然被文件系统锁定而且我'我无法更新它的新版本(这是使用动态加载的全部原因)。
该应用程序使用带有Beast websockets的Boost ASIO,我最近做的更改是切换到SSL。我认为我是如何调用或关闭SSL文件系统锁定DLL的连接有问题。但由于FreeLibrary返回成功(以及后续调用FreeLibrary挂起),我不确定为什么DLL文件仍会被锁定。
以下是我在C#(代码段)中加载DLL的方法:
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);
[DllImport("kernel32.dll")]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
private static extern bool FreeLibrary(IntPtr hModule);
IntPtr Handle;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void Initdb();
Initdb InitdbFunction;
主要
Handle = LoadLibrary("Perks.dll");
if (Handle == IntPtr.Zero) {
int errorCode = Marshal.GetLastWin32Error();
throw new Exception(string.Format("Failed to load library (ErrorCode: {0})", errorCode));
}
IntPtr funcaddr;
funcaddr = GetProcAddress(Handle, "Initdb");
InitdbFunction = Marshal.GetDelegateForFunctionPointer(funcaddr, typeof(Initdb)) as Initdb;
卸载功能
if (FreeLibrary(Handle))
{
Console.WriteLine("FreeLibrary true");
}
else
{
Console.WriteLine("FreeLibrary false");
}
Handle = IntPtr.Zero;
我在非托管DLL中的新增Boost ASIO和Beast websockets(可能会以某种方式引起问题)就在这里C ++(片段)
std::string wsm_SERVER_URL;
boost::asio::io_service wsm_ios;
boost::asio::io_service::work wsm_work{ wsm_ios };
boost::asio::ip::tcp::resolver wsm_r{ wsm_ios };
boost::asio::ip::tcp::socket wsm_sock{ wsm_ios };
std::unique_ptr<beast::websocket::stream< boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>> wsm_client;
boost::asio::ssl::context wsm_ctx{ boost::asio::ssl::context::sslv23 };
初始化
wsm_client = std::make_unique<beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>>(wsm_ios, wsm_ctx);
使用
wsm_client = std::make_unique<beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>>(wsm_ios, wsm_ctx);
boost::asio::ip::tcp::resolver::iterator iter = wsm_r.resolve(boost::asio::ip::tcp::resolver::query{ wsm_SERVER_URL, "https" });
const boost::asio::ip::tcp::endpoint EP = iter->endpoint();
boost::system::error_code EC;
wsm_client->next_layer().next_layer().connect(EP, EC);
wsm_client->next_layer().set_verify_mode(boost::asio::ssl::verify_none);
wsm_client->next_layer().handshake(boost::asio::ssl::stream_base::client);
wsm_client->handshake(wsm_SERVER_URL, srv_url);
停用(在C#执行FreeLibrary部分之前在C ++中调用)
wsm_client->next_layer().next_layer().close();
wsm_client->next_layer().next_layer().cancel();
wsm_client->close(beast::websocket::close_code::normal);
wsm_client.reset();
wsm_ios.stop();