我有一个 Java 程序,它利用一些 native 函数调用来加速视频编码。它需要一个 DLL,我将用 C 编写它(我现在只有一个测试)。
当我使用 cl/I "java-path/include"/"java-path/include/win32"-DL -ML Main.c -FeTest.dll
编译 DLL 时,它会编译,但我得到了一个 32 位 DLL。在互联网上做了一些研究后,我发现我需要一个 64 位 DLL。
经过更多研究,我找到了this post这是 C 的唯一一个(甚至 C++ 也很难找到),但这只有在您通过 Visual Studio 2010 编写/构建时才有效。我使用 Elipse 用于 Java,CLion 用于 C,并通过“开发人员”进行编译命令提示符。”所以这对我不起作用。我如何重新编译为 64 位 DLL?
编辑:我正在使用 Visual Studio 2017 附带的 cl.exe
更新:我在 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13 下找到了 64 位的
,但是在运行它时,出现库机器类型 (x86) 与目标类型 (x64) 冲突的错误。如何更改图书馆机器类型?cl.exe
。 26128\bin\Hostx64\x64\cl.exe
最佳答案
正如我在 [SO]: How to build a DLL version of libjpeg 9b? (@CristiFati's answer) 开头所解释的那样(来自 1. Prepare the ground 部分的项目符号),VStudio 中有不同的命令行处理构建的方法。
我将专注于vcvarsall.bat。有关 [MSDN]: Setting the Path and Environment Variables for Command-Line Builds 的更多详细信息(它是 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 路径是自定义的,因为我在“C:\Install\x86\Microsoft\Visual Studio Community\2017 下安装了 VStudio2017 ”。默认路径为“%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。这是要避免的,因为它可能会导致各种讨厌的问题
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 >>>
关于c - 如何编译用 C 编写的 64 位 dll?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50164687/