Gcc 构建包含Mozilla js ctypes库的DLL
我正在尝试构建一个DLL,用于Mozilla Firefox扩展。我在Windows7中使用Cygwin。我的C代码运行良好,它构建正常: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
#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++