Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调用标准C函数fprintf()时,用嵌入式R.dll编译的C程序崩溃_C_R_Dll - Fatal编程技术网

调用标准C函数fprintf()时,用嵌入式R.dll编译的C程序崩溃

调用标准C函数fprintf()时,用嵌入式R.dll编译的C程序崩溃,c,r,dll,C,R,Dll,我正在使用MSVC2013更新5并从Revolution R 3.2.2 x64导入R.dll库,以编译使用embded R.dll的自定义版本Rserve()。CRT类型是多线程调试DLL。以一种非常奇怪的方式调用fprintf(stderr,…)时,程序崩溃: ntdll.dll!RtlRaiseStatus() Unknown ntdll.dll!string "Enabling heap debug options\n"() Unknown ntdll.dll!RtlEnterCri

我正在使用MSVC2013更新5并从Revolution R 3.2.2 x64导入R.dll库,以编译使用embded R.dll的自定义版本Rserve()。CRT类型是多线程调试DLL。以一种非常奇怪的方式调用fprintf(stderr,…)时,程序崩溃:

ntdll.dll!RtlRaiseStatus()  Unknown
ntdll.dll!string "Enabling heap debug options\n"()  Unknown
ntdll.dll!RtlEnterCriticalSection() Unknown
msvcrt.dll!_lock_file() Unknown
msvcrt.dll!putc()   Unknown
R.dll!000000006c8dd814()    Unknown
R.dll!000000006c8df8e8()    Unknown
R.dll!000000006c8e3d74()    Unknown
R.dll!000000006c8dd00d()    Unknown
RServe.exe!loadConfig(const char * fn) Line 2113    C
RServe.exe!main(int argc, char * * argv) Line 4247  C
[External Code] 
代码如下所示:

 if(checkScriptFileName(p) != 0)
        fprintf(stderr, "Error: Invalid script file name: '%s'.\n", p);
根据我的理解,fprintf()应该位于msvcr120d.dll中,但它以某种方式访问msvcrt.dll并通过R.dll

有人面临过类似的问题吗?你能建议一下,在这种情况下我能做些什么来解决这个问题?(对于那些不了解这个问题的人来说)问题是如何修复这个崩溃(这通常不应该发生,因为我已经将所有正确的参数传递给了fprintf())

更新:更有趣的细节-尝试切换到CRT的静态变体,得到以下有趣的东西:

1>  Generating Code...
1>LIBCMTD.lib(sprintf.obj) : error LNK2005: sprintf already defined in R.lib(R.dll)
1>LIBCMTD.lib(printf.obj) : error LNK2005: printf already defined in R.lib(R.dll)

我想出了下面的解决办法。以下是我从R.dll手动生成导入库的脚本:

:: Read more at the http://stackoverflow.com/questions/9946322/how-to-generate-an-import-library-lib-file-from-a-dll
setlocal
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64
SET MACHINE=x64
SET LIBNAME=R
dumpbin /exports %LIBNAME%.dll > %LIBNAME%.exports
echo LIBRARY R > %LIBNAME%.def
echo EXPORTS >> %LIBNAME%.def
for /f "skip=19 tokens=4" %%A in (%LIBNAME%.exports) do echo %%A >> %LIBNAME%.def
start /wait win32pad.exe %LIBNAME%.def
lib /def:%LIBNAME%.def /out:%LIBNAME%.lib /machine:%MACHINE%
endlocal
实际上,我已经添加了这个

start /wait win32pad.exe %LIBNAME%.def
在运行lib.exe之前。这将启动文本编辑器,允许我手动编辑DEF文件,并从中删除所有版本的“printf”(有多个版本),它们实际上应该来自本机工具集的CRT版本

在与调整后的导入库链接后,问题就消失了


我希望这将是有用的信息的人谁的目标是嵌入到他们的Windows应用程序的R

您知道R Core的官方立场是,任何与MSVC有关的内容都是不受支持的。R是用MinGW工具链构建的,这无关紧要。这的确是一个糟糕的设计。即使使用MinGW,任何DLL都不应该导出在C运行时库中找到的符号。不幸的是,当涉及后期调试时,所有MinGW可执行文件都变得无用。在这里阅读更多。我也尝试过提到那里的工具cv2pdb,它对我没有帮助-只是没有用标准的GCC生成的调试信息从EXE生成正确的PDB。将错误报告发布到R Bugzilla,希望他们能在以后的版本中修复。事实上,只需要手动定义文件并排除DLL中由于某种原因可能发生的所有CRT内容(或者更好,完全排除CRT内容)。因此,当MINGW能够为可执行文件/DLL生成具有完整特性的PDB文件(无论是仅此文件还是标准Formart(如DWARF)之外的文件)时,我将选择MINGW。