Swi prolog的C#接口中的System.AccessViolationException
我是新来的,我希望我能找到解决问题的办法。问题的背景如下:Swi prolog的C#接口中的System.AccessViolationException,c#,.net,wcf,swi-prolog,C#,.net,Wcf,Swi Prolog,我是新来的,我希望我能找到解决问题的办法。问题的背景如下: 我正在尝试构建一个专家系统,该系统构成一个与Swi prolog交互的C#前端 我已经下载了SwiPlCs.dll(一个连接.NET语言和Swi Prolog的CSharp类库) 并在Visual Studio项目(Win form app)中添加了对它的引用,我创建该项目是为了测试是否可以从c#查询prolog(我遵循了找到的文档中使用的示例) 它工作得很好 然后,在一个更复杂的场景中,我构建了一个WCF服务,它将充当Swi Pro
- 我正在尝试构建一个专家系统,该系统构成一个与Swi prolog交互的C#前端李>
- 我已经下载了
(一个连接.NET语言和Swi Prolog的CSharp类库)SwiPlCs.dll
- 并在Visual Studio项目(Win form app)中添加了对它的引用,我创建该项目是为了测试是否可以从c#查询prolog(我遵循了找到的文档中使用的示例)
- 它工作得很好
- 然后,在一个更复杂的场景中,我构建了一个WCF服务,它将充当Swi Prolog和C#client应用程序之间的中介层(它使用该服务)
- 该服务托管在IIS 7.0中
- 为了简单起见,假设我的服务包含三种方法。
- 第一个方法初始化prolog引擎,查阅prolog源文件,然后查询该文件
- 第二个方法执行另一个查询
- 第三个方法调用PlCleanup()
Application: w3wp.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
堆栈:
at SbsSW.SwiPlCs.SafeNativeMethods.PL_new_term_ref()
at SbsSW.SwiPlCs.PlQuery..ctor(System.String, System.String)
at SbsSW.SwiPlCs.PlQuery..ctor(System.String)
at PrologQueryService.PrologQueryService.DetermineAgeGroup(Int32)
尝试在第一个方法结束时关闭引擎,并在第二个方法中再次初始化它
除非您反对,否则您可以将此作为问题的答案进行检查。尝试在第一个方法结束时关闭引擎,并在第二个方法中再次初始化它
除非您反对,否则您可以将此复选框作为问题的答案。我还尝试将此接口用于.NET项目 查看CSharp界面与SWI Prolog的连接,我注意到该项目非常古老,官方网站下载页面上的二进制文件中似乎没有最新的更新 然后我做了以下步骤:
- 专用于.NET的contrib存储库表明兼容的SWI Prolog版本(在编写本文时)为“8.0.3-1”(请参阅)。 ->然后我从我的计算机上卸载了最新的stable,并安装了指定的一个。我是从这个网站上下载的旧版本的完整列表中得到的
- 我克隆了SWI-Prolog/contrib-swiplcs存储库,从解决方案中卸载了不兼容的项目,因为我不使用visualstudio。 ->我将目标框架设置为NETFramework4.8,并重新编译了它(您也可以使用标准的Net进行此操作)。注意旧项目文件中定义的一些pragma指令(例如,我通过代码重新定义了_PL_X64变量)
- 我将主要的单元测试方法引入到xUnit的一个新项目中,并进行了适当的更改
- 我将目标设置为x64,重新编译并重建了测试和“hello world”示例
我还尝试将该接口用于.NET项目 查看CSharp界面与SWI Prolog的连接,我注意到该项目非常古老,官方网站下载页面上的二进制文件中似乎没有最新的更新 然后我做了以下步骤:
- 专用于.NET的contrib存储库表明兼容的SWI Prolog版本(在编写本文时)为“8.0.3-1”(请参阅)。 ->然后我从我的计算机上卸载了最新的stable,并安装了指定的一个。我是从这个网站上下载的旧版本的完整列表中得到的
- 我克隆了SWI-Prolog/contrib-swiplcs存储库,从解决方案中卸载了不兼容的项目,因为我不使用visualstudio。 ->我将目标框架设置为NETFramework4.8,并重新编译了它(您也可以使用标准的Net进行此操作)。注意旧项目文件中定义的一些pragma指令(例如,我通过代码重新定义了_PL_X64变量)
- 我将主要的单元测试方法引入到xUnit的一个新项目中,并进行了适当的更改
- 我将目标设置为x64,重新编译并重建了测试和“hello world”示例
在调用DetermineAgeGroup(int age)方法时,将在哪一行抛出异常。在这一行中:使用(var query=new PlQuery(“age_group(+age+”,G)”)在哪个实例化模式下您的WCF服务工作(PerCall,Single,Per Session)?它设置为Per Session,并发模式为singleHmmm。PerSession和单并发模式是正确的。尝试编译所有针对x86平台的程序集。有时,这种互操作性问题可能是由x64平台的编译引起的。在哪一行引发异常?在调用DetermineAgeGroup(int age)方法时。在这一行中:使用(var query=new PlQuery(“age_group(“+age+”,G)”)在其中inst
public void QuitProlog()
{
if (PlEngine.IsInitialized)
{
PlEngine.PlCleanup();
}
}
Application: w3wp.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
at SbsSW.SwiPlCs.SafeNativeMethods.PL_new_term_ref()
at SbsSW.SwiPlCs.PlQuery..ctor(System.String, System.String)
at SbsSW.SwiPlCs.PlQuery..ctor(System.String)
at PrologQueryService.PrologQueryService.DetermineAgeGroup(Int32)
[Fact]
public void ShouldLoadAProgramAndUseIt()
{
var pathValues = Environment.GetEnvironmentVariable("PATH");
pathValues += @";C:\Program Files\swipl\bin";
Environment.SetEnvironmentVariable("PATH", pathValues);
// Positioning to project folder
var currentDirectory = Directory.GetCurrentDirectory().Split('\\').ToList();
currentDirectory.RemoveAll(r => currentDirectory.ToArray().Reverse().Take(3).Contains(r));
var basePath = currentDirectory.Aggregate((c1, c2) => $"{c1}\\{c2}");
var filePath = $"{basePath}\\prolog_examples\\exec_checker.pl";
String[] param = { "-q", "-f", filePath };
PlEngine.Initialize(param);
try
{
var query = "exutable('2020-08-15',[('monthly', ['2019-12-30', '2020-03-10'])])";
_testOutputHelper.WriteLine($"Query: {query}");
using (var q = new PlQuery(query))
{
var booleanAnswer = q.NextSolution();
_testOutputHelper.WriteLine($"Answer: {booleanAnswer}");
Assert.True(booleanAnswer);
}
query = "exutable('2020-08-15',[('daily', ['2019-12-30', '2020-08-15'])])";
_testOutputHelper.WriteLine($"Query: {query}");
using (var q = new PlQuery(query))
{
var booleanAnswer = q.NextSolution();
_testOutputHelper.WriteLine($"Answer: {booleanAnswer}");
Assert.False(booleanAnswer);
}
}
finally
{
PlEngine.PlCleanup();
}
}