Как скомпилировать 64-битную DLL, написанную на C? - PullRequest
0 голосов
/ 04 мая 2018

У меня есть программа на Java, которая использует некоторые вызовы собственных функций для ускорения кодирования видео. Для этого требуется DLL, которую я напишу на C (сейчас у меня только тестовая).

Когда я компилирую DLL с cl /I "java-path/include" /"java-path/include/win32" -DL -ML Main.c -FeTest.dll, она компилируется, но я получаю 32-битную DLL. Проведя некоторые исследования в Интернете, я обнаружил, что вместо этого мне понадобится 64-битная DLL.

После дополнительных исследований я нашел этот пост , который является единственным для C (даже C ++ было трудно найти), но это работает, только если вы пишете / строите с помощью Visual Studio 2010. I Я использую Elipse для Java, CLion для C и компилирую через «Командную строку разработчика». так что это не работает для меня. Как мне перекомпилировать как 64-битную DLL?

РЕДАКТИРОВАТЬ: я использую cl.exe, который поставляется с Visual Studio 2017

ОБНОВЛЕНИЕ: Я обнаружил 64-битный cl.exe в C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin\Hostx64\x64\cl.exe, однако при его запуске я получаю сообщение об ошибке, что тип библиотечного компьютера (x86) конфликтует с целевым типом (x64). Как изменить тип библиотечного компьютера?

1 Ответ

0 голосов
/ 04 мая 2018

Как я объяснил в начале [SO]: Как создать версию DLL libjpeg 9b? (@ Ответ CristiFati) (маркеры из 1. Подготовьте наземную секцию ), есть разные способы построения из командной строки в VStudio .
Я собираюсь сосредоточиться на vcvarsall.bat . Подробнее о [MSDN]: установка переменных пути и среды для сборок командной строки (это VStudio2015 , поскольку VStudio2017 связь прервана).
Я подготовил фиктивный пример.

code.c

#include <stdio.h>
#include "jni.h"


__declspec(dllexport) int func() {
    JavaVMInitArgs args;
    printf("Pointer size: %lld bits\n", sizeof(void*) * 8);
    printf("JNI_GetDefaultJavaVMInitArgs returned: %d\n", JNI_GetDefaultJavaVMInitArgs(&args));
    return 0;
}

Сложение :

e:\Work\Dev\StackOverflow\q050164687>"c:\Install\x86\Microsoft\Visual Studio Community\2017\VC\Auxiliary\Build\vcvarsall.bat" amd64
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.6.6
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

e:\Work\Dev\StackOverflow\q050164687>dir /b
code.c

e:\Work\Dev\StackOverflow\q050164687>cl /nologo /LD /I"c:\Install\x64\Oracle\Java\jdk1.8.0_152\include" /I"c:\Install\x64\Oracle\Java\jdk1.8.0_152\include\win32" /DWIN64 /DWIN32 code.c /link /LIBPATH:"c:\Install\x64\Oracle\Java\jdk1.8.0_152\lib" /OUT:dummy.dll jvm.lib
code.c
   Creating library code.lib and object code.exp

e:\Work\Dev\StackOverflow\q050164687>dir /b
code.c
code.exp
code.lib
code.obj
dummy.dll

Примечания

  • Мой vcvarsall путь является пользовательским, потому что я установил VStudio2017 в " C: \ Install \ x86 \ Microsoft \ Visual Studio Community \ 2017 ". Путь по умолчанию: «% SystemDrive% \ Program Files (x86) \ Microsoft Visual Studio \ 2017 \ Community »
  • После запуска vcvarsall мне не нужно указывать cl.exe (или link.exe ):
    • Полный путь
    • Параметры сборки (в зависимости от архитектуры, включая пути)
    • Мне все еще нужно указать вещи, о которых он не знает (например, Java вещи)
  • Чтобы протестировать недавно созданную .dll , я собираюсь использовать Python , так как это проще, чем написать другую .c программу, которая использует он
  • Поскольку я связал .dll с jvm.lib , во время выполнения потребуется jvm.dll , поэтому я добавляю его путь в % PATH%
  • Я собрал свой код с помощью VStudio2017 ( VCRuntime14.0 ), но jvm.dll связан с VCRuntime10.0 ( VStudio2010 ), что означает, что в моей программе будет загружено (по крайней мере) 2 VCRuntime s. Этого следует избегать, поскольку это может привести к всевозможным неприятным проблемам
e:\Work\Dev\StackOverflow\q050164687>set PATH=%PATH%;c:\Install\x64\Oracle\Java\jdk1.8.0_152\jre\bin\server

e:\Work\Dev\StackOverflow\q050164687>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe"
Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> dummy = ctypes.CDLL("dummy.dll")
>>> dummy.func()
Pointer size: 64 bits
JNI_GetDefaultJavaVMInitArgs returned: -1
0
>>>
...