- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在 C# 中动态加载一个 DLL,这样我就可以在执行时卸载它。我找到了一些文章,但没有一篇真正对我有帮助。我需要卸载 DLL,因为它没有提供任何释放/清理内存的功能。实际问题:它是一个硬件驱动程序 (CAN-USB),如果硬件断开连接,我需要重新启动我的应用程序,这非常烦人。如果我可以将它加载到程序集(或类似的东西)中,我可以分别“卸载”它“重新加载”它。我需要一个简短但相关的示例,说明如何加载我的 dll 以及如何导入和使用 dll 函数。我附上了我现在如何使用它们的屏幕截图。
我需要总结的:
有关如何动态加载(附加类型的)dll 以及如何使用其功能的示例。
如何在硬件断开的情况下卸载/重新加载dll。
如果有任何建议,我将不胜感激。
编辑 1:我现在已经按照 this 中的描述实现了它方法,但它没有解决我的问题。 CAN-USB-Hardware 会阻塞,直到我关闭我的应用程序并重新启动它。我是不是做错了什么,或者有人对如何解决我最初的问题有任何其他建议吗?
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,因此您正在从 native 程序集中导入函数,因此您需要使用将在 native 语言中使用的相同函数:LoadLibrary、GetProcAddress、FreeLibrary。这些函数执行以下任务:
LoadLibrary : Loads the DLL into memory and returns a raw address ofthe DLL’s handle. If the DLL cannot be found, returns IntPtr.Zero.
GetProcAddress : Loads a function by name from the DLL. Returns a rawaddress of the function. If the function cannot be found, returnsIntPtr.Zero.
FreeLibrary : Releases the DLL loaded by the LoadLibraryfunction.
使用 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# - 在 C# 中动态加载和使用 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27859420/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!