delphi – 链接sqlite3.obj会发出不满意的前向声明错误
我使用以下命令从sqlite3.c和BCC 55编译了SQLIte3数据库引擎:
bcc32.exe -jb -O2 -w- -K -c -6 -u- sqlite3.c 生成了正确的sqlite3.obj文件.但是,一旦我尝试在我的Delphi应用程序中链接它,如下所示: unit unt_SQLite3; interface uses Windows; implementation {$LINK 'sqlite3.obj'} end. 我收到以下错误: [DCC Error] E2065 Unsatisfied forward or external declaration: '__ftol' [DCC Error] E2065 Unsatisfied forward or external declaration: '__lldiv' [DCC Error] E2065 Unsatisfied forward or external declaration: '__llmod' [DCC Error] E2065 Unsatisfied forward or external declaration: '_localtime' [DCC Error] E2065 Unsatisfied forward or external declaration: '_strncmp' [DCC Error] E2065 Unsatisfied forward or external declaration: '_memset' [DCC Error] E2065 Unsatisfied forward or external declaration: '__llmul' [DCC Error] E2065 Unsatisfied forward or external declaration: '_malloc' [DCC Error] E2065 Unsatisfied forward or external declaration: '_free' [DCC Error] E2065 Unsatisfied forward or external declaration: '_realloc' [DCC Error] E2065 Unsatisfied forward or external declaration: '_memcpy' [DCC Error] E2065 Unsatisfied forward or external declaration: '__llumod' [DCC Error] E2065 Unsatisfied forward or external declaration: '__lludiv' [DCC Error] E2065 Unsatisfied forward or external declaration: '_memmove' [DCC Error] E2065 Unsatisfied forward or external declaration: '_memcmp' [DCC Error] E2065 Unsatisfied forward or external declaration: '__llshl' [DCC Error] E2065 Unsatisfied forward or external declaration: '__llshr' [DCC Error] E2065 Unsatisfied forward or external declaration: '_atol' [DCC Error] E2065 Unsatisfied forward or external declaration: '_strlen' [DCC Error] E2065 Unsatisfied forward or external declaration: '_qsort' [DCC Error] E2065 Unsatisfied forward or external declaration: '__llushr' [DCC Error] E2065 Unsatisfied forward or external declaration: '__turboFloat' 为什么需要在纯pascal(或asm)中实现Borland C运行时函数? 做这个mysqlf而不是使用SynSQLite3或DIXml的理由如下: > SynSQLite3支持3.7.8(我没看到最新的3.7.9) 最终我最终选择了SynSQLite3,因为: >它是开源的 附:我的sqlite3.obj暂时可以下载并测试here 解决方法
看看我们的开源库.它实现了sqlite3.obj的静态链接,并使用最新版本的SQLite3官方代码进行维护(和功能 – 它是唯一允许扩展使用SQLite3虚拟表的框架).你有一个包装器.但不止于此.
以下是我们如何将源代码编译成.obj(一个包含FTS3,另一个没有它): del sqlite3.obj devbccbinbcc32 -6 -O2 -c -d -DSQLITE_ENABLE_FTS3 -u- sqlite3.c copy sqlite3.obj sqlite3fts3.obj devbccbinbcc32 -6 -O2 -c -d -u- sqlite3.c 然后看一下SynSQLite3.pas单元.它包含一些所需外部文件的纯pascal或asm版本. 例如: function _ftol: Int64; // Borland C++ float to integer (Int64) conversion asm jmp System.@Trunc // FST(0) -> EDX:EAX,as expected by BCC32 compiler end; function _ftoul: Int64; // Borland C++ float to integer (Int64) conversion asm jmp System.@Trunc // FST(0) -> EDX:EAX,as expected by BCC32 compiler end; function malloc(size: cardinal): Pointer; cdecl; { always cdecl } // the SQLite3 database engine will use the FastMM4/SynScaleMM fast heap manager begin GetMem(Result,size); end; procedure free(P: Pointer); cdecl; { always cdecl } // the SQLite3 database engine will use the FastMM4 very fast heap manager begin FreeMem(P); end; function realloc(P: Pointer; Size: Integer): Pointer; cdecl; { always cdecl } // the SQLite3 database engine will use the FastMM4/SynScaleMM very fast heap manager begin result := P; ReallocMem(result,Size); end; function memset(P: Pointer; B: Integer; count: Integer): pointer; cdecl; { always cdecl } // a fast full pascal version of the standard C library function begin result := P; FillChar(P^,count,B); end; procedure memmove(dest,source: pointer; count: Integer); cdecl; { always cdecl } // a fast full pascal version of the standard C library function begin Move(source^,dest^,count); // move() is overlapping-friendly end; procedure memcpy(dest,source: Pointer; count: Integer); cdecl; { always cdecl } // a fast full pascal version of the standard C library function begin Move(source^,count); end; function atol(P: pointer): integer; cdecl; { always cdecl } // a fast full pascal version of the standard C library function begin result := GetInteger(P); end; var __turbofloat: word; { not used,but must be present for linking } // Borland C++ and Delphi share the same low level Int64 _ll*() functions: procedure _lldiv; asm jmp System.@_lldiv end; procedure _lludiv; asm jmp System.@_lludiv end; procedure _llmod; asm jmp System.@_llmod end; procedure _llmul; asm jmp System.@_llmul end; procedure _llumod; asm jmp System.@_llumod end; procedure _llshl; asm jmp System.@_llshl end; procedure _llshr; asm {$ifndef ENHANCEDRTL} // need this code for Borland/CodeGear default System.pas shrd eax,edx,cl sar edx,cl cmp cl,32 jl @@Done cmp cl,64 jge @@RetSign mov eax,edx sar edx,31 ret @@RetSign: sar edx,31 mov eax,edx @@Done: {$else} // our customized System.pas didn't forget to put _llshr in its interface :) jmp System.@_llshr {$endif} end; procedure _llushr; asm jmp System.@_llushr end; function strlen(p: PAnsiChar): integer; cdecl; { always cdecl } // a fast full pascal version of the standard C library function begin // called only by some obscure FTS3 functions (normal code use dedicated functions) result := SynCommons.StrLen(pointer(p)); end; function memcmp(p1,p2: pByte; Size: integer): integer; cdecl; { always cdecl } // a fast full pascal version of the standard C library function begin if (p1<>p2) and (Size<>0) then if p1<>nil then if p2<>nil then begin repeat if p1^<>p2^ then begin result := p1^-p2^; exit; end; dec(Size); inc(p1); inc(p2); until Size=0; result := 0; end else result := 1 else result := -1 else result := 0; end; function strncmp(p1,p2: PByte; Size: integer): integer; cdecl; { always cdecl } // a fast full pascal version of the standard C library function var i: integer; begin for i := 1 to Size do begin result := p1^-p2^; if (result<>0) or (p1^=0) then exit; inc(p1); inc(p2); end; result := 0; end; function localtime(t: PCardinal): pointer; cdecl; { always cdecl } // a fast full pascal version of the standard C library function var uTm: TFileTime; lTm: TFileTime; S: TSystemTime; begin Int64(uTm) := (Int64(t^) + 11644473600)*10000000; // unix time to dos file time FileTimeToLocalFileTime(uTM,lTM); FileTimeToSystemTime(lTM,S); with atm do begin tm_sec := S.wSecond; tm_min := S.wMinute; tm_hour := S.wHour; tm_mday := S.wDay; tm_mon := S.wMonth-1; tm_year := S.wYear-1900; tm_wday := S.wDayOfWeek; end; result := @atm; end; 你会发现这个单元不仅仅是SQLite3的静态链接.请注意,即使我们的mORMot ORM客户端 – 服务器框架使用它,也不需要使用此ORM来使用SQLite3类.见this article for additional details. 如果您迷失在我们的源代码库中(使用伟大的FOSSIL项目),read this. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |