【发布时间】:2014-09-14 03:43:16
【问题描述】:
我已经阅读了大量关于如何解决我的问题的文章、教程和说明,但仍然没有收获。我就是不能把它付诸实践。
我的目标很简单:我想使用 Cygwin gcc 工具编译一个 DLL 文件,然后在 MSVC2010 中使用它。我实际上想用我自己的 DLL 代码来做,但为了简单起见——我在 Cygwin 的网站上尝试了非常基本的例子——但也失败了..
到目前为止我做了什么: (大部分内容来自 Cygwin 用户指南,DLL section)
-
创建
mydll.c文件如下:#include <stdio.h> int hello() { printf ("Hello World!\n"); } 使用
gcc -c mydll.c和gcc -shared -o mydll.dll mydll.o将mydll.c编译成mydll.dll-
在 Visual Studio 中打开了一个空的 Win32 控制台项目,代码如下:
test.c(代码取自Oleg 在here 中的代码,基于this):#include <windows.h> typedef int (*PFN_HELLO)(); typedef void (*PFN_CYGWIN_DLL_INIT)(); int main() { PFN_HELLO fnHello; HMODULE hLib, h = LoadLibrary(TEXT("cygwin1.dll")); PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT)GetProcAddress(h,"cygwin_dll_init"); init(); hLib = LoadLibrary (TEXT("D:\\test\\mydll.dll")); fnHello = (PFN_HELLO) GetProcAddress (hLib, "hello"); return fnHello(); } 在 Windows 系统上设置路径变量以包含“Cygwin\bin\”目录。
构建并运行。
我最终遇到了以下异常:0xc0000005: Access violation reading location 0x003a0048.
这是完整的 MSVC2010 调试输出:
'CygwinDLLTest.exe': Loaded 'C:\Users\xxxx\Documents\Visual Studio 2010\Projects\CygwinDLLTest\Debug\CygwinDLLTest.exe', Symbol loaded.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\ntdll.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\kernel32.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\kernelBase.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\msvcr100d.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'D:\Cygwin\bin\cygwin1.dll', Binary was not built with debug information.
cYgFFFFFFFF 6119F510 0cYgstd 0x27a70b d 3'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\user32.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\gdi32.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\lpk.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\usp10.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\msvcrt.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\advapi32.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\sechost.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\rpcrt4.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\sspicli.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\cryptbase.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\imm32.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'C:\Windows\SysWOW64\msctf.dll', cannot find or open the PDB file.
'CygwinDLLTest.exe': Loaded 'D:\test\mydll.dll', Binary was not built with debug information.
First-chance exception at 0x611075a8 in CygwinDLLTest.exe: 0xc0000005: Access violation reading location 0x003a0048
Unhandled exception at 0x611075a8 in CygwinDLLTest.exe: 0xc0000005: Access violation reading location 0x003a0048
The program '[784] CygwinDLLTest.exe: Native' has exited with code 0 (0x0).
现在,重要的是要注意问题不在于加载这些 DLL,因为它们的处理程序都得到了一个不同于 NULL 的地址。导致异常的代码行是在 DLL 文件中调用 hello 函数。
在你去说任何关于extern "C" 或__declspec(dllimport/dllexport) 的事情之前 - 不会有帮助。我已经尝试了所有这些并没有帮助。(虽然,AFAIK - 我在 MS 方面使用 Explicit Linking,在 UNIX 方面使用 Dynamic Loading,所以 @987654346 @ 不是必需的)。
我真的希望问题不在于堆栈定义,因为 over here:
“确保堆栈底部有 4K 的暂存空间”
因为我不知道如何在 MSVC2010 上实现这一点(显然,Oleg...:) 也不知道
现在,我知道在Hans Passant 的话中直接提到了我的问题而不是here - 仍然 - 我不明白如何解决我的问题。
更新:我正在更新这个,因为我想我知道问题的原因,我只是不知道如何解决它。请原谅我,Arkady,但我真的不认为它与你提到的所有内容有任何关系。我正在使用非常简单的 .dll 文件,它只有一个功能,所以没有什么可以“包装”在那里..
无论如何,我认为我的问题是使用 msvcrt.dll 文件,而不是 here 所说的:
问:我可以同时链接 MSVCRT*.DLL 和 cygwin1.dll 吗?
A:不,你必须使用其中一个,它们是互斥的。
我知道我正在链接他们两个,我只是不知道如何说服 Visual Studio 仅链接到 cygwin1.dll 单独..
我会回答这个问题。
【问题讨论】:
标签: c++ visual-studio-2010 gcc dll cygwin