在开始这个过程之前,我想知道要做多少工作?我们是在谈论一个重大的任务,还是有一种简单直接的解决方案?我懂一些C语言,但并不是专家。
我不需要关于SoX的具体细节,只需了解EXE控制台应用程序转换为DLL的一般情况。如果有人熟悉SoX,那就更好了。
如果所有内容都是使用 printf、scanf 和其它类似函数完成的,那么你最好是找到/创建一个包含文件,让所有源文件都包含它,并添加一个宏,将 printf/scanf 等重定向到你自己编写的函数,使其适合 DLL 实现。像 printf 这样的东西可以从 vsnprintf 中构建(出于安全考虑,请使用 n 版本),因此你不需要重新实现整个 C RTL I/O 子系统。但是,没有 vsscanf,但是网上有第三方实现。
如果代码使用 fprintf、fscanf 等来在文件和控制台之间进行间接操作,那么你还是没有办法。FILE 结构是不透明的,并且与 Pascal 文本文件不同,不能实现便携式文本文件驱动程序。如果你深入研究特定的 C RTL,可能仍然有可能,但是最好选择宏路线并重新实现您自己的重命名 FILE 类型。
最后,"popen()" 方法在 Delphi 中是可行的,并且在 Delphi 2009 中使用 TTextReader 和 TTextWriter 类会更容易。将这些与围绕管道的 TFileStream 结合起来,并在新进程中指定标准输入、标准输出和标准错误的管道以及 STARTF_USESTDHANDLES 等,它就能正常工作了。如果你不想编写自己的代码,网上也有第三方等效/示例可供 Delphi 使用。这里有一个。
您甚至可能不需要DLL,可以使用popen()函数来运行控制台应用程序并收集任何输出文本。
按照Indiv的建议运行进程,并像Adam所示一样捕获输出。
然而,如果您仍然想进行DLL转换,以下内容可以帮助您入门。
Add a new Function called DLLMain
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID ) {return TRUE;}
Add a .DEF file (use the project name as the file name) that lists the exports in the DLL - Add the following content to it
LIBRARY "name.DLL"
EXPORTS
CallOldMain PRIVATE
Rename the main of SOX as CallOldMain
Write a CUSTOM function to log the output / return error etc.
Find all printfs / cout in the SOX application and replace it with calls to your custom function above
Once the DLL is compiled you can now call the function CallOldMain with the same parameters main programs of C expects. You could modify this signature to return the errors / output from above.
您没有提到您的工具链是什么,但如果您在Windows中配置gcc,则可以使用正常的config;make;make install来编译sox。在此过程中,它将创建一个dll文件和控制台应用程序。或者,您只需指定make目标只制作dll即可。这将编译一个仅依赖于MS C运行时dll的Windows本机库,您可以在自己的应用程序中使用它。