【问题标题】:Why aren't there pre-built PInvoke DLLs?为什么没有预构建的 PInvoke DLL?
【发布时间】:2015-01-14 02:57:44
【问题描述】:

我正在构建一个使用几个 user32.dll 函数和几个 gdi32.dll 函数的 PowerShell 脚本。我过去曾多次这样做。

我厌倦了在我的 PowerShell 代码中以字符串形式查看这些巨大的 C# 代码块。我也厌倦了必须为我打算使用的每个单独函数找到 PInvoke 代码。我想要一个 DLL 来包装所有(已知的)user32.dll 函数,这样我就可以一劳永逸地使用它们。

我搜索了一下,似乎无法为 user32.dll、win32.dll 或其他流行的非托管 dll 中的所有已知函数找到任何预构建的 PInvoke 包装 DLL。为什么是这样?我知道它们可能不稳定并且需要不断更新 - 这是原因吗?

我还注意到http://pinvoke.net/ 提供了一个自动生成签名的 Visual Studio 插件...这是否意味着有一个 pinvoke.net 网络服务,我可以使用它来根据他们的最新状态自动生成一个 dll数据库?

【问题讨论】:

  • 这听起来像是SWIG 可以解决的问题?但我知道我对 Java 并不满意,所以我想出了自己的工具,名为 JavaCPP...
  • 你可以自己写。是什么阻止你?基于 pinvoke.net 的自动生成将是一个坏主意,因为那里的内容质量低。
  • 我刚刚找到了网络服务:pinvoke.net/pinvokeservice.asmx,所以我想我会自己写它并很快发布到这里。 function PInvoke($module){...}
  • 有很多框架类实际上在后台使用 p/invoke!
  • 这变得非常困难,因为 pinvoke.net 中的许多条目都是为人工解释而设计的。

标签: powershell dll pinvoke unmanaged managed


【解决方案1】:

Internet 上没有预先构建的 DLL,以及为什么没有人使用 PInvoke.net 的 Web 服务来自动执行此操作的原因是,那里的大多数数据对人类来说是可以理解和解释的,但对人类来说却不是很好。通过自动脚本消费。但是,如果它被清理一吨,它可能是可能的。

许多此类信息仍存储在 msdn 上,但创建包含所有已知函数的此类包装 DLL 需要时间。 AFAIK,还没有人这样做过。我很想花时间浏览 user32.dll 中的 586 个已知函数并创建一个可供其他人使用的包装 DLL,但我只是没有时间,因为我想大多数人都会这样做.我认为微软没有这样做仅仅是因为他们认为这不值得他们花时间。

此外,其中一些函数的构建方式似乎甚至可能没有正确的方法来转换为托管代码,并且可以肯定它们会起作用。特别是,解释哪些 C# 类型应该用于 C 指针似乎是一个问题。

【讨论】:

  • char* ... stringStringBuilderref char 之类的东西还有很多含义?这些事情使自动翻译变得复杂。
【解决方案2】:

您可以轻松使用您提到的 P/Invoke 网络服务。我试了一下,发现 P/Invoke 数据库的格式完全不正确,无法通过脚本导入。它不是以定义的方式构造的,因此您要么必须提出某种“智能解析”,要么自己修复错误,这将是太多的工作! kernel32.dll 已经产生了 4000 行代码,更不用说其他数百个库了。

这是我到目前为止所做的,当放入 C# 文件时,结果是不可编译的。过滤掉“TODO”项目是一回事,但许多项目还包含语法错误,引用其他未明确定义的结构等等......问题很简单,数据库没有任何类型的明确格式。这只是用户可以在其中输入文本的纯文本字段。

使用以下脚本的结果时出现 127 个编译错误。我想这是你能得到的最接近的。

PInvokeServiceSoapClient client = new PInvokeServiceSoapClient();
client.Open();
foreach (FunctionInfo function in client.SearchFunction("kernel32.dll", new WikiVersion()))
{
    Console.WriteLine(function.Function);
    try
    {
        foreach (SignatureInfo signature in client.GetResultsForFunction(function.Function, function.Module))
        {
            if (signature.Language == "C#")
            {
                if (!signature.Signature.Contains("TODO"))
                {
                    if (!signature.Summary.StartsWith("TODO"))
                    {
                        Console.WriteLine("/// <summary>\r\n/// " + signature.Summary + "\r\n/// </summary>");
                    }
                    Console.WriteLine(signature.Signature.Replace("|", "\r\n"));
                }
            }
        }
    }
    catch { }
}
client.Close();

也许有一天你会想出一个创意来创建一个包含所有 WinAPI 函数并充当所有内容的包装器的 DLL。会很酷!

【讨论】:

    猜你喜欢
    • 2012-08-21
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 2012-10-22
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    相关资源
    最近更新 更多