10

我有 MinGW,我希望将SQLite 合并源编译成 64 位 dll。我对这种编译还很陌生,到目前为止我的努力都失败了。(我首先开始使用 autoconf 合并,并在 Linux 上使用了 configure & make 工具。但显然这对 Windows 二进制文件不起作用。)

无论如何,有人告诉我我需要以下预处理器定义:

以下是我用于 64 位版本构建的编译器预处理器定义:

  • WIN64 NDBUG
  • _视窗
  • _USRDLL
  • NO_TCL
  • _CRT_SECURE_NO_DEPRECATE
  • 线程安全=1
  • TEMP_STORE=1
  • SQLITE_MAX_EXPR_DEPTH=0

以下是我用于 32 位发布版本的编译器预处理器定义:

  • WIN32
  • NDBUG
  • _视窗
  • _USRDLL
  • NO_TCL
  • _CRT_SECURE_NO_DEPRECATE
  • 线程安全=1
  • TEMP_STORE=1
  • SQLITE_MAX_EXPR_DEPTH=0

我不知道把这些放在哪里。我最终做了一个有根据的猜测,制作了一个名为 sqlite3w64.h 的新文件(为了整洁)并粘贴在以下内容中:

#define WIN64 NDEBUG
#define _WINDOWS
#define _USRDLL
#define NO_TCL
#define _CRT_SECURE_NO_DEPRECATE
#define THREADSAFE 1
#define TEMP_STORE 1
#define SQLITE_MAX_EXPR_DEPTH 0

然后我使用以下命令编译了源代码:

gcc sqlitew64.h sqlite3.h sqlite3ext.h shell.c sqlite3.c -o sqlite_x64.dll

结果是一个 733KB 的 DLL 文件。好的!它真的有效吗?是不是疯了——我得到了一个 BadImageFormatException。然后我还尝试使用相同的方法进行 x86 编译。再一次,我得到了一个 733KB 的 DLL 文件(这很奇怪?),再一次,我得到了一个 BadImageFormatException。

帮助。

更新

改用以下命令:

gcc -shared -DWIN64 -DNDEBUG -D_WINDOWS -D_USRDLL -DNO_TCL -D_CRT_SECURE_NO_DEPRECATE -DTHREADSAFE=1 -DTEMP_STORE=1 -DSQLITE_MAX_EXPR_DEPTH=0 -I. shell.c sqlite3.c -o sqlite_x64.dll -Wl,--out-implib,sqlite3.a

生成一个 740KB 的 DLL 文件,它仍然给出 BadImageFormatException。

最终更新

原来我的 MinGW 版本只有 32 位。获得 64 位版本之后,我就可以制作 64 位的 SQLite。添加标志 -m64 将编译器设置为 64 位模式。

64 位:

gcc -shared -DWIN64 -DNDEBUG -D_WINDOWS -D_USRDLL -DNO_TCL -D_CRT_SECURE_NO_DEPRECATE -DTHREADSAFE=1 -DTEMP_STORE=1 -DSQLITE_MAX_EXPR_DEPTH=0 -m64 -I. shell.c sqlite3.c -o sqlite3_x64.dll -Wl,--out-implib,sqlite3_x64.a

32 位:

gcc -shared -DWIN32 -D_WINDOWS -D_USRDLL -DNO_TCL -D_CRT_SECURE_NO_DEPRECATE -DTHREADSAFE=1 -DTEMP_STORE=1 -DSQLITE_MAX_EXPR_DEPTH=0 -m32 -I. shell.c sqlite3.c -o sqlite3_x86.dll -Wl,--out-implib,sqlite3_x86.a

MinGW-64 预编译:http: //sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds/mingw-w64-bin_i686-mingw_20111220.zip/download ?use_mirror=ignum

安装说明:http ://code.google.com/p/tonatiuh/wiki/InstallingMinGWForWindows64

4

2 回答 2

7

您正在编译为 EXE。将其称为 DLL 不会神奇地使其成为 DLL。

您需要将特殊的链接器选项传递给 gcc 以使其创建 DLL。引自 Mingw 网站:(有点,我用 gcc 替换了 g++)

gcc -c -DBUILDING_EXAMPLE_DLL example_dll.cpp
gcc -shared -o example_dll.dll example_dll.o -Wl,--out-implib,libexample_dll.a

该页面还解释了您希望 DLL 导出的函数必须使用__declspec(dllexport). (再往下,有一个关于如何将所有全局函数导出到 DLL 的示例,就像在 Unix 中通常发生的那样。)

gcc的-Wl参数告诉 gcc 将进一步的参数--out-imlib,libexample_dll.a传递给链接器。

我还会100%确定构建的 DLL 实际上是 64 位 DLL 而不是 32 位 DLL。你有什么方法可以检查吗?在 Linux 上,您可以运行“文件”命令。

您还可以尝试将-m64选项添加到 gcc 命令行,这将强制gcc 以 amd64 目标为目标。

如果不起作用,则您可能完全使用了错误的编译器。确保您拥有Mingw 工具链的 x86_64/amd64 版本。安装就像找到正确的 ZIP、解压缩并设置路径一样简单。

如果所有这些都失败了,或者如果您只是想验证一个假定正确编译的设置,请在此处或从此处尝试预编译的 64 位二进制文​​件

于 2012-06-11T10:14:52.740 回答
4

在您的情况下,这个单一的链接和编译命令会起作用:

g++ -shared
-DWIN64
-DNDEBUG
-D_WINDOWS
-D_USRDLL
-DNO_TCL
-D_CRT_SECURE_NO_DEPRECATE
-DTHREADSAFE=1
-DTEMP_STORE=1
-DSQLITE_MAX_EXPR_DEPTH=0
-I.
shell.c sqlite3.c
-o sqlite_x64.dll
-Wl,--out-implib,libsqllite_x64.dll.a

编译和链接阶段将立即执行。可以在命令行上添加定义。头文件不需要编译,但需要将当前目录作为头文件搜索目录传递,并指定dll和导入文件的名称。

于 2012-06-11T10:21:35.030 回答