首页 / C# / 在C#中动态加载和使用DLL
在C#中动态加载和使用DLL
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了在C#中动态加载和使用DLL,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7630字,纯文字阅读大概需要11分钟。
内容图文
我想在C#中动态加载DLL,这样我就可以在执行时将其卸载.我找到了一些文章,但没有任何帮助.我需要卸载DLL,因为它不提供释放/清理内存的任何功能.实际的问题:它是一个硬件驱动程序(CAN-USB),如果硬件断开连接,我需要重新启动应用程序,这很烦人.如果我可以将其加载到装配体(或类似的东西)中,则可以“卸载”或“重新加载”它.我将需要一个简短而简约的示例,但相关的示例如何加载我的dll以及如何导入和使用dll函数.我附上了截图,说明我现在如何使用它们.
我需要总结的是:
>有关如何动态加载dll(附加类型)以及如何使用其功能的示例.
>在硬件断开的情况下如何解除引导/重新加载dll.
我将不胜感激任何建议.
编辑1:
我现在已经实现了它,就像this方法中描述的那样,但是它不能解决我的问题. CAN-USB-硬件会阻塞,直到我关闭我的应用程序并再次启动它.我做错了什么吗?有人对解决最初的问题有其他建议吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace InDiPro
{
public struct canData
{
public uint id;
public uint length;
public byte data0;
public byte data1;
public byte data2;
public byte data3;
public byte data4;
public byte data5;
public byte data6;
public byte data7;
}
public class EsdCanDriver
{
private IntPtr pDll;
private string dllPath;
private IntPtr fptrCanOpen;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanOpen(int net, int mode, int txqueueSize, int rxqueueSize, int txTimeout, int rxTimeout, ref int handle);
private static CanOpen _canOpen;
public int canOpen(int net, int mode, int txqueueSize, int rxqueueSize, int txTimeout, int rxTimeout, ref int handle)
{
return _canOpen(net, mode, txqueueSize, rxqueueSize, txTimeout, rxTimeout, ref handle);
}
private IntPtr fptrCanClose;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanClose(int handle);
private static CanClose _canClose;
public int canClose(int handle)
{
return _canClose(handle);
}
private IntPtr fptrCanSetBaudrate;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanSetBaudrate(int handle, int baudrate);
private static CanSetBaudrate _canSetBaudrate;
public int canSetBaudrate(int handle, int baudrate)
{
return _canSetBaudrate(handle, baudrate);
}
private IntPtr fptrCanGetBaudrate;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanGetBaudrate(int handle, ref int baudrate);
private static CanGetBaudrate _canGetBaudrate;
public int canGetBaudrate(int handle, ref int baudrate)
{
return _canGetBaudrate(handle, ref baudrate);
}
private IntPtr fptrCanIdAdd;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanIdAdd(int handle, int id);
private static CanIdAdd _canIdAdd;
public int canIdAdd(int handle, int id)
{
return _canIdAdd(handle, id);
}
private IntPtr fptrCanIdDelete;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanIdDelete(int handle, int id);
private static CanIdDelete _canIdDelete;
public int canIdDelete(int handle, int id)
{
return _canIdDelete(handle, id);
}
private IntPtr fptrCanSend;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanSend(int handle, ref canData msg, ref int length);
private static CanSend _canSend;
public int canSend(int handle, ref canData msg, ref int length)
{
return _canSend(handle, ref msg, ref length);
}
private IntPtr fptrCanTake;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanTake(int handle, ref canData msg, ref int length);
private static CanTake _canTake;
public int canTake(int handle, ref canData msg, ref int length)
{
return _canTake(handle, ref msg, ref length);
}
private IntPtr fptrCanWrite;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanWrite(int handle, ref canData msg, ref int length, ref int dummy);
private static CanWrite _canWrite;
public int canWrite(int handle, ref canData msg, ref int length, ref int dummy)
{
return _canWrite(handle, ref msg, ref length, ref dummy);
}
private IntPtr fptrCanRead;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int CanRead(int handle, ref canData msg, ref int length, ref int dummy);
private static CanRead _canRead;
public int canRead(int handle, ref canData msg, ref int length, ref int dummy)
{
return _canRead(handle, ref msg, ref length, ref dummy);
}
public EsdCanDriver(string dllPath)
{
this.dllPath = dllPath;
}
public bool LoadDriver()
{
pDll = NativeMethods.LoadLibrary(this.dllPath);
if(pDll == IntPtr.Zero)
{
return false;
}
else
{
fptrCanOpen = NativeMethods.GetProcAddress(pDll, "__canOpen@28");
if (fptrCanOpen == IntPtr.Zero) return false;
_canOpen = (CanOpen)Marshal.GetDelegateForFunctionPointer(fptrCanOpen, typeof(CanOpen));
fptrCanClose = NativeMethods.GetProcAddress(pDll, "__canClose@4");
if (fptrCanClose == IntPtr.Zero) return false;
_canClose = (CanClose)Marshal.GetDelegateForFunctionPointer(fptrCanClose, typeof(CanClose));
fptrCanSetBaudrate = NativeMethods.GetProcAddress(pDll, "__canSetBaudrate@8");
if (fptrCanSetBaudrate == IntPtr.Zero) return false;
_canSetBaudrate = (CanSetBaudrate)Marshal.GetDelegateForFunctionPointer(fptrCanSetBaudrate, typeof(CanSetBaudrate));
fptrCanGetBaudrate = NativeMethods.GetProcAddress(pDll, "__canGetBaudrate@8");
if (fptrCanGetBaudrate == IntPtr.Zero) return false;
_canGetBaudrate = (CanGetBaudrate)Marshal.GetDelegateForFunctionPointer(fptrCanGetBaudrate, typeof(CanGetBaudrate));
fptrCanIdAdd = NativeMethods.GetProcAddress(pDll, "__canIdAdd@8");
if (fptrCanIdAdd == IntPtr.Zero) return false;
_canIdAdd = (CanIdAdd)Marshal.GetDelegateForFunctionPointer(fptrCanIdAdd, typeof(CanIdAdd));
fptrCanIdDelete = NativeMethods.GetProcAddress(pDll, "__canIdDelete@8");
if (fptrCanIdDelete == IntPtr.Zero) return false;
_canIdDelete = (CanIdDelete)Marshal.GetDelegateForFunctionPointer(fptrCanIdDelete, typeof(CanIdDelete));
fptrCanSend = NativeMethods.GetProcAddress(pDll, "__canSend@12");
if (fptrCanSend == IntPtr.Zero) return false;
_canSend = (CanSend)Marshal.GetDelegateForFunctionPointer(fptrCanSend, typeof(CanSend));
fptrCanTake = NativeMethods.GetProcAddress(pDll, "__canTake@12");
if (fptrCanTake == IntPtr.Zero) return false;
_canTake = (CanTake)Marshal.GetDelegateForFunctionPointer(fptrCanTake, typeof(CanTake));
fptrCanWrite = NativeMethods.GetProcAddress(pDll, "__canWrite@16");
if (fptrCanWrite == IntPtr.Zero) return false;
_canWrite = (CanWrite)Marshal.GetDelegateForFunctionPointer(fptrCanWrite, typeof(CanWrite));
fptrCanRead = NativeMethods.GetProcAddress(pDll, "__canRead@16");
if (fptrCanRead == IntPtr.Zero) return false;
_canRead = (CanRead)Marshal.GetDelegateForFunctionPointer(fptrCanRead, typeof(CanRead));
return true;
}
}
public bool FreeDriver()
{
return NativeMethods.FreeLibrary(pDll);
}
}
}
解决方法:
您正在使用DLLImport,因此要从本机程序集中导入函数,因此需要使用与本机语言相同的函数:LoadLibrary,GetProcAddress,FreeLibrary.
这些功能执行以下任务:
LoadLibrary : Loads the DLL into memory and returns a raw address of
the DLL’s handle. If the DLL cannot be found, returns IntPtr.Zero.GetProcAddress : Loads a function by name from the DLL. Returns a raw
address of the function. If the function cannot be found, returns
IntPtr.Zero.FreeLibrary : Releases the DLL loaded by the LoadLibrary
function.
使用LoadLibrary的示例可能是:
IntPtr address = win32.GetProcAddress(m_dll, moduleName);
System.Delegate fn_ptr = Marshal.GetDelegateForFunctionPointer(address, typeof(T));
虽然FreeLibrary的示例可能是:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr GetModuleHandle(string moduleName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool FreeLibrary(IntPtr hModule);
// Unload the DLL by calling GetModuleHandle and FreeLibrary.
FreeLibrary(GetModuleHandle(moduleName));
内容总结
以上是互联网集市为您收集整理的在C#中动态加载和使用DLL全部内容,希望文章能够帮你解决在C#中动态加载和使用DLL所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。