【问题标题】:How to compile a 64-bit dll written in C?如何编译用 C 编写的 64 位 dll?
【发布时间】:2018-05-03 22:33:18
【问题描述】:

我有一个 Java 程序,它利用一些本机函数调用来加速视频编码。它需要一个 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,C 的 CLion,并通过“开发人员命令提示符”进行编译。所以这对我不起作用。如何重新编译为 64 位 DLL?

编辑:我正在使用 Visual Studio 2017 附带的 cl.exe

更新:我在 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin\Hostx64\x64\cl.exe 下找到了 64 位 cl.exe,但是在运行它时,我收到一个错误,即库机器类型 (x86) 与目标类型 (x64) 冲突。如何更改库机器类型?

【问题讨论】:

  • @jdv 它忽略它,所以没有
  • @c0degreen 不重复,但相关:stackoverflow.com/questions/2548138/…
  • @jdv 我必须澄清一下,它是 Visual Studio 编译器 (cl.exe)。你知道我可以使用的替代方法吗?
  • edit这个问题并清楚您使用的是什么工具链。
  • 您使用的是开发人员命令提示符还是 x64 本机工具命令提示符?

标签: c dll compilation 64-bit x86-64


【解决方案1】:

正如我在[SO]: How to build a DLL version of libjpeg 9b? (@CristiFati's answer) 开头所解释的(来自1.准备地面部分的项目符号),在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
>>>

【讨论】:

    猜你喜欢
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2014-08-15
    • 2017-03-08
    • 1970-01-01
    • 2019-05-01
    相关资源
    最近更新 更多