前言
之前写Winform程序的时候需要对Sqlite数据库进行操作,查找资料之后得知System.Data.Sqlite中有对应的函数,于是就去下载了个程序集导入。本来以为这和Java使用Sqlite数据库一样简单,调包就行了(其实原理一样,但是这个dll有点特殊而已),谁想到后面一连串的报错,居然弄了好几个小时,故此作为记录,也能给后来者一些指引。
由于报错太多,笔者已经忘记了一些报错发生的顺序和内容,只能给一个大概的描述,希望读者谅解。毕竟笔者那时候快赶上DEADLINE,加上报错太多,一度以为已经无路可走只能放弃,所以也没有留心记录错误。
程序集运行时版本报错
报错详细信息:混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
这个报错的解决方式比较简单,只需要程序对应的修改app.config文件即可(如果是在类库中调用此包,就在使用类库的程序的config文件中修改)。
解决方式:在app.config的startup键中加入下文,其中版本号改为报错中的版本号:
<supportedRuntime version="v2.0.50727"/>
程序集调用内存报错
报错详细信息:C# 尝试读取或写入受保护的内存,这通常指示其他内存已损坏。
这个报错是因为此程序集调用了封装后的C++的程序集,在C++程序集里产生了错误。这个问题是最难解决的,因为调用C++程序集甚至都没有发生在自己写的代码里,最差就需要下载C++程序集的源码排错重新编译了。
解决方式:我找了半天,最后到System.Data.Sqlite官网找到了最新的用于.NET的程序集,用它替换了目前的程序集然后运行,成功了。官网链接如下:System.Data.SQLite: Downloads Page
找不到Interop.dll
报错详细信息:System.DllNotFoundException:“无法加载 DLL“SQLite.Interop.dll”: 找不到指定的模块。
这个报错是由于Sqlite程序集会调用由C++编写的库SQLite.Interop.dll,这些调用以[DllImport]方式被定义在了源码中的UnsafeNativeMethods.cs文件内。
解决方式:下载一个SQLite.Interop.dll文件,并放在编译出来的exe文件目录下。
Any CPU下运行报错(未能加载依赖项)
报错详细信息:System.IO.FileLoadException:“未能加载文件或程序集“System.Data.SQLite,……”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。
这个报错要追溯到Sqlite C#程序集的“出身”了。总而言之,作为C#程序集的System.Data.Sqlite其实是由包含了C#与C/C++两种语言的项目编译出来的一部分,需要依赖于另一个C/C++库(也就是Sqlite.Interop),而此C++库是分32与64位的。也正是因为此,Sqlite程序集在AnyCPU的情况下可能会发生报错。
解决方式:如果要求不高,可以确定使用x64或x86的方式生成,并且使用对应位数的Interop库文件。最新版本的Sqlite程序集貌似也不会发生报错,但这未经证明。