use*_*291 -1 c# c++ dll pinvoke loadlibrary
有以下C#代码用于加载和卸载C++ DLL.
我只加载DLL一次,但代码必须卸载DLL 2次.在卸载DLL之后,当我再次加载它,并且我调用DLL的导出函数时,我收到以下错误消息:
尝试读取或写入受保护的内存.这通常表明其他内存已损坏.
DLL依赖于其他DLL.
/// //////////////handle of FDD DLL:
System.IntPtr SystemIntPtr_handle_of_DLL=System.IntPtr.Zero;
private void button4_Click(object sender, EventArgs e)
{
try
{
string string_Dependency_path = ".\\DLL_Dependencies\\";
Call_DLL.SetDllDirectory(string_Dependency_path);
SystemIntPtr_handle_of_DLL = Call_DLL.LoadLibrary("DLL.dll");
if (SystemIntPtr_handle_of_DLL == System.IntPtr.Zero) { throw new Exception("DLL did not load"); }
}
catch (Exception Exception_Object) { MessageBox.Show(Exception_Object.Message); }
}
private void button5_Click(object sender, EventArgs e)
{
try
{
int int_FreeLibrary_counter = 0;
while (Call_DLL.FreeLibrary(SystemIntPtr_handle_of_DLL))
{
int_FreeLibrary_counter++;
}
MessageBox.Show("DLL unloaded. You will have to load it again. (Unloaded" + int_FreeLibrary_counter + " times)");
}
catch (Exception Exception_Object) { MessageBox.Show(Exception_Object.Message); }
}
Run Code Online (Sandbox Code Playgroud)
调用方法:
class Call_DLL
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetDllDirectory(string string_Dependency_path);
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string string_DLL_name);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FreeLibrary(IntPtr IntPtr_handle_of_DLL);
}
Run Code Online (Sandbox Code Playgroud)
我忘了在加载DLL之后和卸载DLL之前包含以下调用DLL导出函数的内容.认为在这些导出的函数中发生了其他事情是有意义的,这会导致奇怪的行为(即加载1次,必须卸载2次):
[DllImport(@"DLL.dll", EntryPoint = "getFreq")]
public static extern System.IntPtr getFreq([In, Out, MarshalAs(UnmanagedType.LPStr)] string char_Address, [In, Out, MarshalAs(UnmanagedType.I4)]int int_Num, [In, Out, MarshalAs(UnmanagedType.I4)]int int_Samp);
[DllImport(@"DLL.dll", EntryPoint = "setNat")]
public static extern System.IntPtr setNat([In, Out, MarshalAs(UnmanagedType.LPStr)]string char_Address_File_nat);
[DllImport(@"DLL.dll", EntryPoint = "getMode")]
public static extern System.IntPtr getMode();
Run Code Online (Sandbox Code Playgroud)
对您的问题的更新提供了足够的信息来解释行为.
LoadLibrary
加载您的DLL,其中包含其中一个引用.DllImport
p/invoke函数,这反过来导致调用LoadLibrary
.这是对图书馆的另一个参考.FreeLibrary
,由于有两次调用,这次成功两次LoadLibrary
.但是现在你遇到了麻烦,因为你已经落后于p/invoke系统,它仍然认为它拥有对DLL的一个引用.你第二次打电话给你偷的参考FreeLibrary
.
我猜你丢失的信息是DllImport
p/invokes 如何绑定到函数.您希望他们通过调用获取模块句柄GetModuleHandle
.他们没有.他们打电话LoadLibrary
.它们在第一次调用时执行此操作,并且它们加载的模块保持加载状态,直到程序集本身卸载为止.
你最重要的是遵循规则.规则规定每次呼叫都要LoadLibrary
通过呼叫进行匹配FreeLibrary
.你打电话LoadLibrary
一次.所以你也必须打FreeLibrary
一次电话.停止打电话两次,一切都很顺利.
我怀疑你实际上是在尝试安排一个可以加载和卸载DLL的系统.这可以防止您使用p/invoke via DllImport
.你必须用LoadLibrary
和完成所有这些GetProcAddress
.
你对SetDllDirectory
外观的使用有些搞砸了.你期望".\\DLL_Dependencies\\"
相对于什么?提供完整的路径.
归档时间: |
|
查看次数: |
1400 次 |
最近记录: |