Gcc 构建包含Mozilla js ctypes库的DLL

Gcc 构建包含Mozilla js ctypes库的DLL,gcc,dll,firefox-addon,mozilla,jsctypes,Gcc,Dll,Firefox Addon,Mozilla,Jsctypes,我正在尝试构建一个DLL,用于Mozilla Firefox扩展。我在Windows7中使用Cygwin。我的C代码运行良好,它构建正常: #include<stdio.h> #include<windows.h> BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { return TRUE; } extern "C" { __declspec(dlle

我正在尝试构建一个DLL,用于Mozilla Firefox扩展。我在Windows7中使用Cygwin。我的C代码运行良好,它构建正常:

#include<stdio.h>
#include<windows.h>

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
  return TRUE;
}

extern "C"
{
    __declspec(dllexport) int add(int a,int b) //int a,int b
    {
        return(a+b);
    }
}
我使用的是
i686-w64-mingw32-g++
而不是
gcc/g++
,因为DLL无法以其他方式打开。我不知道为什么


任何帮助都将不胜感激。

我不太明白所问的问题,但可能是为什么Cygwin gcc(或mingw-w64 gcc)正在生成一个您无法
ctypes.open()的DLL

Cygwin gcc生成的dll确实对某些Cygwin dll具有外部依赖性,至少是提供posix抽象的
cygwin1.dll
。 将这些DLL与您的附加组件一起运送是一件痛苦的事情,而且不是一件明智的事情

您需要使用mingw编译器(例如
i686-w64-mingw32-g++
one)。您也可以使用Microsoft或Intel编译器

好的,mingw-w64现在是:

$ i686-w64-mingw32-g++ -shared -o test_add.dll test_add.cc
$ objdump -p test_add.dll
The Import Tables (interpreted .idata section contents)
...
DLL Name: KERNEL32.dll
...
DLL Name: msvcrt.dll
...
The Export Tables (interpreted .edata section contents)
...
[Ordinal/Name Pointer] Table
        [   0] add
好的,我们的DLL导入了
kernel32.DLL
msvcrt.DLL
,并且没有任何意外,还导出了我们的
add

那么,让我们试试看:

var lib = ctypes.open("C:\\cygwin\\home\\user\\test_add.dll");
try {
    try {
        var adder = lib.declare("add", ctypes.default_abi, ctypes.int32_t, ctypes.int32_t, ctypes.int32_t);
        console.log(adder(3,5));
    }
    catch(ex) {
        console.error(ex, ex.message);
    }
}
finally {
    lib.close();
}
生成输出:
8

接下来,所有二进制文件都应该启用ASLR

$ peflags -v test_add.dll
test_add.dll: coff(0x2106[+executable_image,+line_nums_stripped,+32bit_machine,+dll]) pe(0x0000)
事实证明,它不是(没有动态数据库)

因此,让我们改进链接器命令:

$ i686-w64-mingw32-g++ -shared -o test_add.dll test_add.cc -Wl,-nxcompat,-dynamicbase
$ peflags -v test_add.dll
test_add.dll: coff(0x2106[+executable_image,+line_nums_stripped,+32bit_machine,+dll]) pe(0x0140[+dynamicbase,+nxcompat])
那好吧

但不幸的是,这还不是全部。编译
C++
并使用某些功能时,链接器将自动链接到
stdlibc++
中,例如使用
std::string

将一个
std::string
添加到源代码,重新编译/重新链接,以及另一个
objdump
告诉我们:

DLL Name: libgcc_s_sjlj-1.dll
vma:  Hint/Ord Member-Name Bound-To
7470       16  _Unwind_SjLj_Register
7488       17  _Unwind_SjLj_Resume
74a0       19  _Unwind_SjLj_Unregister

DLL Name: libstdc++-6.dll
vma:  Hint/Ord Member-Name Bound-To
74bc      743  _ZNSaIcEC1Ev
74cc      746  _ZNSaIcED1Ev
74dc     1080  _ZNSsC1EPKcRKSaIcE
74f4     1105  _ZNSsD1Ev
7500     3535  __gxx_personality_sj0
在这种情况下,您还必须提供这些库(确保
peflags
ASLR位并遵循许可证),或者避免任何可能产生异常或需要
stdlibc++
的情况。 或者您可以静态链接这些内容:

i686-w64-mingw32-g++ -shared -o test_add.dll test_add.cc -Wl,-nxcompat,-dynamicbase -static-libgcc -static-libstdc++

当然,静态链接会增大输出DLL的大小。

我创建了一个库,用js ctypes从我的firefox扩展中调用,效果很好。不幸的是,我只在ubuntu linux上尝试过这个,所以我不确定你的问题是什么。然而,我也遇到了同样的问题,直到我发现有必要指定一个编译器开关来指定“位置独立代码”。这个开关是gnu编译器上的-fPIC。我不是100%确定这是你的问题,但是找出你需要的开关并尝试一下。谁知道呢,也许这是你唯一的问题。我不确定你是否也需要在windows上定位独立的代码,但也许你需要。
i686-w64-mingw32-g++ -shared -o test_add.dll test_add.cc -Wl,-nxcompat,-dynamicbase -static-libgcc -static-libstdc++