从托管代码引用非托管库、优点和缺点?

发布于 09-07 19:45 字数 928 浏览 9 评论 0原文

大家好,

我想从我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

差↓一点笑了2024-09-14 19:45:58

你的第二个比第一个复杂得多,但在这种情况下实现了相同的目标。

如果 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.

陈甜2024-09-14 19:45:58

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文