2013-12-04 1 views
0

Я пытаюсь создать DLL, которая будет использоваться в расширении Mozilla Firefox. Я использую Cygwin в Windows 7. У меня есть код C работает нормально, и он строит нормально:Построение библиотеки DLL, содержащей библиотеки Mozilla js-ctypes

#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); 
    } 
} 

Я следовал инструкциям здесь: Build a DLL to be used by Mozilla js-ctypes.

Проблема заключается в том, что, когда я пытаюсь включить другую библиотеку, ИС-ctypes не может читать DLL впоследствии:
[10:20:53.575] Error: couldn't open library C:\Users\admin\workspaces\Extensions\formfinder\components\test.dll @ chrome://formfinder/content/overlay.js:104

Все, что я добавить в свой файл C является #include <ZZ.h> в верхней части, которая затем дополняются команды замыкающих:

i686-w64-mingw32-g++ -c -I/usr/local/include/NTL -I/usr/local/include test.cc 
i686-w64-mingw32-g++ -shared -o test.dll test.o -Wl,--out-implib,libmylib.dll -Wl,[email protected] 

Я использую i686-w64-mingw32-g++ вместо gcc/g++, потому что DLL не может быть открыта в противном случае. Однако я не знаю, почему.

Любая помощь будет оценена по достоинству.

+0

Я создал библиотеку для вызова из моего расширения firefox с помощью js-ctypes, и он отлично работает. К сожалению, я только пробовал это на ubuntu linux, поэтому я не уверен, в чем проблема. Тем не менее, у меня была такая же проблема, пока я не нашел где-то, что необходимо указать компилятор, чтобы указать «независимый по позиции код». Этот переключатель был -fPIC для компиляторов gnu. Я не уверен на 100%, это ваша проблема, но узнайте, какой коммутатор вам нужен, и попробуйте. Кто знает, может, это твоя единственная проблема. Я не знаю наверняка, что вам тоже нужен независимый код на окнах, но, может быть, и так. – honestann

ответ

1

Я не совсем понимаю, что задают, но, вероятно, почему Cygwin gcc (или mingw-w64 gcc) создает DLL, вы не можете ctypes.open().

DLL, создаваемые Cygwin gcc, имеют внешние зависимости от некоторых библиотек Cygwin, по крайней мере cygwin1.dll, предоставляя абстракцию posix. Отправка этих DLL с помощью вашего дополнения - это боль, а не настоящая нормальная работа.

Вы хотите использовать компилятор mingw (например, i686-w64-mingw32-g++). Вместо этого вы можете использовать компилятор Microsoft или Intel.

OK, 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) 

Оказывается, это не является (не DYNAMICBASE)

Итак, давайте улучшить нашу команду компоновщика:

$ 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, конечно.