从托管代码引用非托管库、优点和缺点?
大家好,
我想从我的 C# 代码中调用非托管库函数,如下所示。有两种选择,并且两者都有效。此时“Beep”函数很简单,没有输入/输出参数、指针、引用...我想知道在更复杂的情况下这两种方法的优点和缺点是什么?
谢谢, 米兰。
[DllImport("kernel32.dll")]
public static extern bool Beep(uint iFreq, uint iDuration);
public void TestBeep()
{
Beep(300, 3000);
}
internal delegate bool DelegBeep(uint iFreq, uint iDuration);
[DllImport("kernel32.dll")]
internal static extern IntPtr LoadLibrary(String dllname);
[DllImport("kernel32.dll")]
internal static extern IntPtr GetProcAddress(IntPtr hModule, String procName);
public void BeepIt()
{
IntPtr kernel32 = LoadLibrary("Kernel32.dll");
IntPtr procBeep = GetProcAddress(kernel32, "Beep");
DelegBeep delegBeep = Marshal.GetDelegateForFunctionPointer(procBeep, typeof(DelegBeep)) as DelegBeep;
delegBeep(50, 1000);//Hz,ms
}
HI all,
I would like to call from my C# code, unamanaged library functions like presented below. There are two options and the both works. In this moment "Beep" function is simple and have no input/output parameters, pointers, references... I am wondering in more complex cases what would be adventages and disadvantage of both approches ?
Thanks,
Milan.
[DllImport("kernel32.dll")]
public static extern bool Beep(uint iFreq, uint iDuration);
public void TestBeep()
{
Beep(300, 3000);
}
internal delegate bool DelegBeep(uint iFreq, uint iDuration);
[DllImport("kernel32.dll")]
internal static extern IntPtr LoadLibrary(String dllname);
[DllImport("kernel32.dll")]
internal static extern IntPtr GetProcAddress(IntPtr hModule, String procName);
public void BeepIt()
{
IntPtr kernel32 = LoadLibrary("Kernel32.dll");
IntPtr procBeep = GetProcAddress(kernel32, "Beep");
DelegBeep delegBeep = Marshal.GetDelegateForFunctionPointer(procBeep, typeof(DelegBeep)) as DelegBeep;
delegBeep(50, 1000);//Hz,ms
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的第二个比第一个复杂得多,但在这种情况下实现了相同的目标。
如果 DLL 的名称和函数的名称在编译时已知,则坚持使用第一种方法。如果您直到运行时才知道 DLL 和/或函数的名称,那么
LoadLibary
/GetProcAddress
方法是您唯一的选择。Your second one is much more complicated than the first but achieves the same thing in this case.
If the name of the DLL and the name of the function are known at compile time, then stick with the first approach. If you don't know the name of the DLL and/or function until run time then the
LoadLibary
/GetProcAddress
approach is your only option.P/Invoke 编组器通过使用 LoadLibrary() 和 GetProcAddress() 查找 DLL 中的入口点。并知道如何将 C# 声明转换为等效的委托声明。
自己做这件事除了可能提高一点点效率之外没有任何优势。你最好衡量一下,这并不是灌篮高手。
The P/Invoke marshaller finds an entrypoint in a DLL by using LoadLibrary() and GetProcAddress(). And knows how to convert a C# declaration to the equivalent of a delegate declaration.
Doing this yourself has no advantage beyond maybe a wee bit of efficiency. Which you'd better measure, it is no slamdunk.