如何编译用C编写的64位dll?

时间:2018-05-03 22:33:18

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

我有一个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,CLion用于C,并通过" Developer命令提示符进行编译。"所以这对我不起作用。我如何重新编译为64位DLL?

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

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

1 个答案:

答案 0 :(得分:1)

正如我在[SO]: How to build a DLL version of libjpeg 9b? (@CristiFati's answer)开头所解释的那样(来自 1。预备地面部分的子弹),有不同的方法来处理 VStudio中命令行的构建< / em>的。
我将专注于 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 < / em>( 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
>>>