【问题标题】:swi-cs-pl create engine with resource fileswi-cs-pl 用资源文件创建引擎
【发布时间】:2023-03-25 22:42:01
【问题描述】:

我事先已经创建了我的 prolog 文件,我想通过 SbsSW.SwiPlCs 库在我的 c# 项目中调用它,所以我将 prolog 文件添加到了我的 Resources 项目文件夹 (vuelos.pl)。

到目前为止,我有以下代码:

private String file = "Properties.Resources.vuelos";
        public Prolog()
        {
            //read file
            String[] param = { "-q", "-f", file};

            try
            {
                PlEngine.Initialize(param);
                //get my Objects
                using (PlQuery q = new PlQuery("aeropuerto(ID,NAME)"))
                {
                    //I do stuff here (omitted)
                }
            }
            catch (PlException e)
            {
                Console.WriteLine(e.MessagePl);
                Console.WriteLine(e.Message);
            }
            finally
            {
                PlEngine.PlCleanup();
            }
        }

但它会抛出一个ResourceNotFoundException,我不知道如何调用我的文件,我不想使用绝对路径,但如果有任何其他解决方案,我想听听。

【问题讨论】:

  • 所以你有 pl 文件所在的/Applicationfolder/resources/ 文件夹,你想构建一个字符串来显示该文件的实际路径?
  • 是的,确切地说,据我所知,创建 PlEngine 的唯一方法是使用 .pl 文件的路径。

标签: c# ffi swi-prolog


【解决方案1】:

我假设资源文件夹始终位于项目文件夹中,因此相对于您的可执行文件。

如果您使用的是 WinForms,您可以使用 Application.StartupPath 获取应用程序路径,然后将其与您的文件路径结合起来。

你的代码应该是这样的:

string ApplicationPath = Application.StartupPath;
var plFullPath = Path.Combine(ApplicationPath, @"Resources\vuelos.pl");

//read file
String[] param = { "-q", "-f", plFullPath};

或者,如果您想在一行中全部完成:

String[] param = { "-q", "-f", Path.Combine(ApplicationPath, @"Resources\vuelos.pl")};

【讨论】:

  • 感谢您的回答,我尝试了这个解决方案,即使现在路径正确并且 vuelos.pl 在那里我仍然得到 FileNotFoundException。
【解决方案2】:

检查环境变量。如果你使用的是 Lesta 的库,它只支持 prolog 版本 6.6.5,这也可能是个问题。

【讨论】:

    【解决方案3】:

    正如user4794198所说,我当前使用的 swi-prolog c# 库与 SWI-prolog 6.6.6 不兼容,所以我下载了 6.6.5 版本。 此外,我将vuelos.pl 文件从\Resources 移动到我的.exe 文件的根文件夹(在\debug 文件夹下),并在c# 上进行了以下调用

     public Prolog()
        {
            //read file
            try
            {
                PlEngine.Initialize(new Object[]);
                //get my Objects
    
                PlQuery.PlCall("consult(vuelos)"); //HERE IS THE CHANGE
    
                using (PlQuery q = new PlQuery("aeropuerto(ID,NAME)"))
                {
                    //I do stuff here (omitted)
                }
            }
            catch (PlException e)
            {
                Console.WriteLine(e.MessagePl);
                Console.WriteLine(e.Message);
            }
            finally
            {
                PlEngine.PlCleanup();
            }
        }
    

    请记住,为了使其正常工作,您应该在其最新版本上引用 SbsSW.SwiPlCs.dll,并且它的架构应该与您安装的 SWI-Prolog 相同。

    如果您使用的是 64 位系统,请记住将下载的 .zip 文件中的 SwiPlCs64.dll 重命名为 SwiPlCs.dll,然后再将其引用到您的项目,就像您在之后执行此操作或更改名称并替换原始SwiPlCs.dll 它可能会在您的项目中创建一些错误的引用并抛出BadImageException

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-19
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 1970-01-01
      • 2012-05-06
      • 1970-01-01
      相关资源
      最近更新 更多