2014-09-11 60 views
1

我已经阅读过大量关于如何解决我的问题的文章,教程和指导 - 但仍然没有收获。我只是不能投入工作。我的目标很简单:我想使用Cygwin gcc工具编译DLL文件,然后在MSVC2010中使用它。我实际上是想用我自己的DLL代码来做,但为了简单起见 - 我已经尝试了Cygwin网站上的基本示例 - 并且失败了。在Visual Studio 2010中使用用Cygwin编译的DLL

到目前为止我所做的: (大部分是从Cygwin的用户指南采取DLL section

  1. 创建mydll.c文件如下:

    #include <stdio.h> 
    
    int hello() { 
        printf ("Hello World!\n"); 
    } 
    
  2. 编译mydll.c到使用和gcc -shared -o mydll.dll mydll.o

  3. 在Visual Studio中打开一个空的Win32控制台项目,用下面的代码(在hereOleg的代码取码,并根据thistest.c

    #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(); 
    } 
    
  4. 套装Windows系统上的路径变量包含“Cygwin \ bin \”目录。

  5. 构建&运行。

我结束了以下异常: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不同的地址。导致异常的代码中的行是调用hello func,在DLL文件中。

而在你走之前说什么关于extern "C"__declspec(dllimport/dllexport) - 不会帮助。我已经尝试过所有这些,但它没有帮助。(虽然,AFAIK - 我根据MS使用Explicit Linking,或者根据UNIX使用Dynamic Loading,所以__declspec(dllimport/dllexport)不是必需的)。

我真的希望这个问题是不是在栈定义,躺在over here

“请确保您有在临时空间4K你栈底”

因为我不知道如何在MSVC2010上做到这一点(显然,Oleg也没有......:)

现在,我知道有一个直接引用我的问题在Hans Passant的话超过here - 仍然 - 我无法理解如何解决我的问题。

更新:我正在更新这个,因为我想我知道是什么原因导致问题,我只是不知道如何解决它。原谅我,Arkady,但我真的不认为它必须对你所提到的所有事情做任何事情。我正在拿真的很简单.DLL文件,只有一个功能,所以没有什么'包装'在那里..
无论如何,我认为我的问题是使用msvcrt.dll文件,而不是什么规定here

Q:我可以用两个MSVCRT * .DLL和cygwin1.dll链接?
答:不,你必须使用一种或另一种,它们是互斥的。

我知道我对链接他们两个,我只是不知道如何说服Visual Studio中只单独对cygwin1.dll链接..

我一个并欣赏回答这个。

+0

http://www.mingw。org/wiki/What_is_a_DLL_and_How_Do_I_Create_or_Use_One可能有用... – rogerdpack 2015-08-21 21:53:41

回答

0

要使用gcc创建DLL并在Visual Studio中使用它,您需要按照下面的步骤:

1)检查您的包装是一样的。我的意思是:

#pragma pack(push, N) 
#pragma pack(pop) 

对于您想要导出的所有结构,函数和数据类型。避免不同的默认数据打包。

2)检查您是否使用外部头文件(即您的导出头文件不包含从外部头文件中提取的任何内容)。我的意思是“windows.h”在VS2010和CygWin中可能会不同。差异通常并不重要,但由于它存在,您可能会遇到问题。 与STL和其他版本一样,版本可能不兼容,因此您将遇到内存问题。

3)检查你是否只输出简单的结构和全局函数。所以,你真的必须导出类似C的界面。 理论告诉,如果你也将出口抽象的接口,如例子:

#pragma pack(push, 4) 
struct A 
{ 
    virtual ~A() {} 
    virtual int32_t DoA() = 0; 
    virtual int32_t PrepareA(const char* settings) = 0; 
}; 

void GlobalFunction(A** ret); 
#pragma pack(pop) 

或避免虚析构函数所有,并添加全局函数,将释放谁在DLL分配对象的内存。由于gcc和msvc-10.0将具有不同的数据管理,因此所有使用gcc分配器分配的内容都必须由gcc deallocator发布。

它必须正常工作,因为通过调用GlobalFunction将在DLL内部初始化,并且会有析构函数,在DLL内部实现。尽管如此,我还是愿意避免它,只用简单的数据和全局函数就可以使用C风格。

4)你也必须确定int在你的gcc和int在你的VS2010有相同的大小。你设置相同的架构。例如,为了避免这个问题,你应该使用int32_t。

5)你应该确保所有导出的dll函数不会抛出异常。完全一样。由相同的记忆问题 - 原因。

相关问题