我有兴趣从另一个Windows GUI程序(自然地用Delphi编写)调用SoX,一个开源控制台应用程序。我不想处理抓取和隐藏控制台窗口,而是将应用程序转换为可以从我的应用程序调用的DLL。
在开始这条道路之前,我很好奇我应该期待多少工作?我们是在谈论一项重大事业,还是有直接的解决方案?我知道一些C,但绝不是专家。
我不期待SoX的具体细节,只是EXE控制台应用程序一般转换为DLL。如果有人熟悉SoX,那就更好了。
答案 0 :(得分:6)
对于通过修改C源代码将控制台可执行文件转换为库的特定主题,它取决于如何分解命令行应用程序。如果它的编写方式使得I / O通过一小组函数或更好的函数指针进行汇集,那么显然它将是微不足道的。
如果全部用printf,scanf和朋友完成,那么你可能最好找到/创建一个包含所有源文件的包含文件,并添加一个宏,将printf / scanf和朋友重定向到你自己的函数编写以便适合DLL实现。像printf这样的东西可以从vsnprintf构建(使用n版本来保证安全),因此您不需要重新实现整个C RTL I / O子系统。但是,没有vsscanf,但网上有第三方实现。
如果代码使用fprintf,fscanf等来启用文件和控制台之间的间接,那你仍然不走运。 FILE结构是不透明的,与Pascal文本文件不同,无法实现可移植文本文件驱动程序。如果您使用特定的C RTL,可能仍然可以使用,但最好建议您沿着宏路线继续并重新实现自己重命名的FILE类型。
最后,在Delphi中可以使用“popen()”方法,并且在Delphi 2009中使用TTextReader和TTextWriter类更容易。将这些与TFileStream包裹在管道中,并在新进程和STARTF_USESTDHANDLES等中为标准输入,标准输出和标准错误指定管道,它将起作用。如果您不想自己编写,也可以在网上为Delphi提供第三方等效/样本。 Here's one.
答案 1 :(得分:5)
在Windows中,只需使用SoX命令行调用CreateProcess即可。我不知道Win32的Delphi绑定,但我在Win32和C#中都做了这个。
现在您知道CreateProcess是您想要调用的内容,谷歌搜索如何从Delphi中执行此操作应该为您提供所需的所有代码。
Delphi Corner Article - Using CreateProcess to Execute Programs
答案 2 :(得分:4)
您甚至可能不需要DLL,您可以使用 popen()功能来运行控制台应用程序并收集任何输出文本。
答案 3 :(得分:3)
免责声明:我对SoX一无所知。可能是代码的结构使这很容易,或者可能更难。无论哪种方式,过程都是一样的:
首先,您要在SoX应用程序中找到要调用的函数。很可能控制台应用程序具有解析命令行并调用适当函数的代码。首先,找到你想要使用的功能。
接下来,查看有关在此网站上从C导出DLL的函数的信息:Creating And Using DLLs
然后创建一个新的makefile或visual studio项目文件,目标是DLL,并从已修改的SoX程序中添加源文件以进行导出。
答案 4 :(得分:3)
运行流程,Indiv建议的方式并捕获输出,就像Adam的表现一样。
但是,如果您仍想进行DLL转换,则可以开始使用
添加一个名为DLLMain的新函数
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID){return TRUE;}
添加一个.DEF文件(使用项目名称作为文件名),列出DLL中的导出 - 向其中添加以下内容
LIBRARY "name.DLL"
EXPORTS
CallOldMain PRIVATE
将SOX的主要部分重命名为CallOldMain
编写CUSTOM函数以记录输出/返回错误等。
在SOX应用程序中查找所有printfs / cout,并将其替换为上述自定义函数的调用
编译DLL后,您现在可以使用C期望的主程序调用函数CallOldMain。您可以修改此签名以从上面返回错误/输出。
答案 5 :(得分:1)
你没有提到你的工具链是什么,但是如果你在Windows中配置gcc,你可以使用普通的配置; make; make install来编译sox。在此过程中,它将创建一个dll文件和控制台应用程序。或者,您只需指定make target即可生成dll。这将编译一个仅依赖于MS C运行时dll的Windows本机库,您可以在自己的应用程序中使用它。
答案 6 :(得分:1)
您可以执行控制台应用程序并使用管道捕获其输出。您使用管道的另一侧作为CreateProcess的stdout,并从另一侧读取,就像一个公共文件。
你可以在这里看到一个用delphi编写的工作示例:http://delphi.about.com/cs/adptips2001/a/bltip0201_2.htm