使用非托管 "dll" 对处理时间的影响。

Effect of using unmanaged "dll" on processing time.

我正在使用名为 VTC7200_IO.dllunmanaged dll。 为了从 dll 中获取函数,我使用下面编写的代码(示例)

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool AllocConsole();

    // Intialise IO Library
    [DllImport("VTC7200_IO.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Library_Initial", CharSet = CharSet.Ansi)]
    public static extern int Library_Initial();

我的问题是,当您重复导入 dll 文件时,processing time 会发生什么情况。任何人都可以给出 conclusive 的答案吗,因为我正在开始一个项目并且正在考虑使用 C# 而不是 C++ 但想知道是否会有很大的不同处理时间。

如果您担心性能,那么您不应将 P/Invoke 与 C# 一起使用,而应使用 C++/CLI 编写包装器。来自 MSDN:

...C++ Interop uses the fastest possible method of data marshaling, whereas P/Invoke uses the most robust method. This means that C++ Interop (in a fashion typical for C++) provides optimal performance by default, and the programmer is responsible for addressing cases where this behavior is not safe or appropriate.

我无法给出关于性能的确切数字,只是如果您使用大量非托管调用,那么将其包装在 C++/CLI class 中会更高效(但不那么健壮)盒子的)而不是仅仅使用 P/Invoke

非托管程序集不是 "loaded repeatedly." 但是,它们确实受到类型封送处理的影响。您可能应该参考 Microsoft Patterns & Practices, Chapter 7 - Improving Interop Performance,它更好地解释了 P/Invoke 的性能注意事项(而且相当详细)。

来自那篇文章:

The process consists of the following steps shown in Figure 7.1.

  1. The runtime intercepts the call to unmanaged code and identifies the target method in the Export Name Table. If a matching method name is found, the method is invoked. For methods that accept ANSI string parameters, the runtime searches for "methodName" and "methodNameA." For methods that accept Unicode string parameters, it searches for "methodName" and "methodNameW."

  2. Parameters are marshaled. These parameters can be marked as [in], [out], or ref. Blittable types (such as System.Byte and System.Int32) do not need to be marshaled and are passed directly across to the unmanaged code. Non-blittable types (such as System.Array) are marshaled (converted), based on default marshaling rules and marshaling hints that you can specify by using attributes such as [MarshalAs(UnmanagedType.LPStr)].

  3. The native code is executed.

  4. Return values are marshaled back. This includes any parameters marked as ByRef, [out], or [in][out] together with a return value, if there is one.