我们正在尝试构建一个访问 SQLite 数据库的 C++ 32 位 DLL。
背景:我们有很多旧版 32 位应用程序。我们的长期目标是主要使用 c++ 和 wxWidgets 将它们转换为 64 位。然而,由于涉及大量的编程,我们无法一次性完成所有这些工作。所以我们决定分期付款。
我们已经做了什么:使用C++ 32位DLL,我们已经转换了几乎所有不涉及访问数据库的全局过程和函数。我们使用 Dev-C++ IDE、MinGW-w64 TDM-GCC 32 位版本。我们能够编译 DLL,并且 32 位应用程序能够毫无问题地调用它们。
此外,我们还可以使用 SQLite ODBC 驱动程序将 SQLite 与我们的应用程序一起使用。然而,我们不想与我们的客户实现这一点,因为它涉及安装驱动程序。我们的应用程序被严格限制在一个文件夹中,我们不会更改该文件夹之外的任何内容。部署就像在客户端驱动器中复制此文件夹一样简单。
我们的问题:当我们尝试在 DLL 中使用 SQLite 时,它只能使用 64 位编译器进行编译,但 DLL 不会加载 32 位应用程序。另一方面,32 位编译器无法引用 SQLite 接口的方法(例如,对“sqlite3_open”的未定义引用)。
我们怀疑它与 libsqlit3.a 的链接有关,该链接可能是 64 位的。我们尝试使用 32 位选项编译 sqlite3.c:
gcc -m32 sqlite3.c -o sqlite3
但它产生了很多错误。
下面是一个 C++ DLL 项目的示例:
testsql.cpp
#include <iostream>
#include <string>
#include "testsql.h"
#include <c:\mingw32\opt\include\sqlite3.h>
using namespace std;
char* sql_char(char* a)
{
string s = "Hello ";
string c = a;
s = s + c;
char *r = &s[0];
return r;
}
/*
**Note: Without the following codes below, the project will compile to 32-bit DLL and will load in 32-bit apps**
*/
int sql_connect(string s)
{
sqlite3* DB;
int exit = 0;
exit = sqlite3_open("c:\\d\\SQLiteDB\\chinook.db", &DB);
if (exit) {
std::cerr << "Error open DB " << sqlite3_errmsg(DB) << std::endl;
return (-1);
}
else
std::cout << "Opened Database Successfully!" << std::endl;
sqlite3_close(DB);
return (0);
}
testsql.h
#pragma once
#ifndef TESTSQL_EXPORTS
#define TESTSQL_API __declspec(dllexport)
#else
#define TESTSQL_API __declspec(dllimport)
#endif
using namespace std;
extern "C" TESTSQL_API char* sql_char(char* a);
extern "C" TESTSQL_API int sql_connect(char* s);
任何帮助将不胜感激。
终于,经过几天的反复尝试,我解决了我们的问题。以下是如何使用 DevCpp 创建 c++ 32 位 DLL:
下载 sqlite-amalgamation-3440000。它包含 4 个文件 - sqlite3.c、shell.c、sqlite3.h 和 sqlite3ext.h。
在放置这些文件的文件夹中,使用这些命令创建 sqlite.o(假设您安装了 gcc 并且包含它的文件夹包含在系统路径中)
gcc -m32 sqlite3.c -c
注意 -m32 是 32 位选项。
回到DevCpp DLL项目,我刚刚添加了sqlite3.o文件的链接:
Project>>Project Options>>Parameters>>Linker
然后重建项目并编译。
我尝试在 VFP 中使用 DLL:
DECLARE INTEGER sql_connect IN c:\d\clics3\SQLite\testsql\test2.dll STRING a
?sql_connect("test")
结果:“0” 程序执行没有任何错误!