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