将控制台exe转换为C中的dll

时间:2020-03-06 14:42:07  来源:igfitidea点击:

我有兴趣从另一个Windows GUI程序(自然用Delphi编写)调用开源控制台应用程序SoX。我只想将应用程序转换为可以从我的应用程序调用的DLL,而不是抓取和隐藏控制台窗口。

在我开始这条道路之前,我很好奇我应该从事多少工作?我们是在说一项重大的任务,还是有直接的解决方案?我知道一些C,但绝不是专家。

我不希望SoX有具体的细节,一般来说,只是将EXE控制台应用程序转换为DLL。如果有人熟悉SoX,那就更好了。

解决方案

我们甚至可能不需要DLL,可以使用popen()函数运行控制台应用程序并收集所有输出文本。

在Windows中,只需使用SoX命令行调用CreateProcess。我不知道Win32的Delphi绑定,但是我已经在Win32和C#中做到了这一点。

既然我们知道CreateProcess就是我们要调用的东西,那么从Delphi进行的有关Google搜索的搜索应会为我们提供所需的所有代码。

Delphi Corner文章使用CreateProcess执行程序

调用CreateProcess()的简单方法

免责声明:我对SoX一无所知。可能是为了简化代码的结构而设计的,或者可能更加困难。无论哪种方式,过程都是相同的:

首先,我们要在SoX应用程序中找到要调用的功能。控制台应用程序很可能具有解析命令行并调用适当功能的代码。因此,首先,找到我们要使用的功能。

接下来,在此站点上检查有关从C导出DLL中的函数的信息:创建和使用DLL。

然后创建一个新的makefile或者Visual Studio项目文件,目标为DLL,并添加已修改为要导出的SoX程序中的源文件。

对于通过修改C源代码将控制台可执行文件转换为库的特定主题,它取决于如何分解命令行应用程序。如果以这样的方式编写I / O:通过一小组函数甚至更好的函数指针进行I / O传递,那么显然这将是微不足道的。

如果这一切都用printf,scanf和friends完成,那么最好找到/创建所有源文件都包含的include文件,并添加一个将printf / scanf和朋友重定向到自己编写的函数的宏,这是最好的以便适合DLL的实现。诸如printf之类的东西可以从vsnprintf构建(为了安全起见,请使用n版本),因此我们无需重新实现整个C RTL I / O子系统。但是,没有vsscanf,但是Web上有第三方实现。

如果代码使用fprintf,fscanf等在文件和控制台之间启用间接访问,则我们仍然很不走运。 FILE结构是不透明的,与Pascal文本文件不同,无法实现可移植文本文件驱动程序。如果我们对特定的C RTL进行拼写,仍然有可能,但是最好还是建议我们沿宏路线执行并重新实现自己重命名的FILE类型。

最后," popen()"方法在Delphi中是可行的,并且在Delphi 2009中使用TTextReader和TTextWriter类使其变得更加容易。将它们与包裹在管道中的TFileStream结合使用,并为新过程中的标准输入,标准输出和标准错误以及STARTF_USESTDHANDLES等指定管道,它将起作用。如果我们不想自己编写代码,那么网上也有Delphi的第三方等效项/示例。这是一个

按照Indiv的建议运行该过程,并像Adam所展示的那样捕获输出。

但是,如果我们仍然想进行DLL转换,这将使我们入门

  • 为Windows配置SOX并对其进行编译
  • 使用C ++工具创建一个空的DLL项目
  • 添加SOX文件作为项目的一部分
  • 添加一个名为DLLMain BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID)的新函数{返回TRUE;}
  • 添加.DEF文件(使用项目名称作为文件名),该文件列出DLL中的导出-向其中添加以下内容
LIBRARY      "name.DLL"

出口CallOldMain私人

  • 将SOX的主要名称重命名为CallOldMain
  • 编写一个CUSTOM函数来记录输出/返回错误等。
  • 在SOX应用程序中找到所有的printfs / cout,并将其替换为对上面的自定义函数的调用
  • 编译完DLL后,我们现在可以使用C主程序期望的相同参数调用函数CallOldMain。我们可以修改此签名以返回错误/从上面输出。

我们没有提到工具链是什么,但是如果我们在Windows中配置gcc,则可以使用常规config; make; make install来编译sox。在此过程中,它将创建一个dll文件和控制台应用程序。或者,我们可以仅指定make目标以仅生成dll。这将编译仅依赖于MS C运行时dll的Windows本机库,我们可以在自己的应用程序中使用它。

我们可以执行控制台应用程序并使用管道捕获其输出。我们将管道的一面用作CreateProcess的stdout,然后从另一面读取,就像一个普通文件。

我们可以在此处查看用delphi编写的工作示例:http://delphi.about.com/cs/adptips2001/a/bltip0201_2.htm