Integrating Prolog with C# - c#

I am new to Prolog and C#. When I try to integrate Prolog with C# I found some errors,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SbsSW.SwiPlCs;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
// Environment.SetEnvironmentVariable("SWI_HOME_DIR", #"the_PATH_to_boot32.prc"); // or boot64.prc
if (!PlEngine.IsInitialized)
{
String[] param = { "-q" }; // suppressing informational and banner messages
PlEngine.Initialize(param);
PlQuery.PlCall("assert(father(martin, inka))");
PlQuery.PlCall("assert(father(uwe, gloria))");
PlQuery.PlCall("assert(father(uwe, melanie))");
PlQuery.PlCall("assert(father(uwe, ayala))");
using (var q = new PlQuery("father(P, C), atomic_list_concat([P,' is_father_of ',C], L)"))
{
foreach (PlQueryVariables v in q.SolutionVariables)
Console.WriteLine(v["L"].ToString());
Console.WriteLine("all children from uwe:");
q.Variables["P"].Unify("uwe");
foreach (PlQueryVariables v in q.SolutionVariables)
Console.WriteLine(v["C"].ToString());
}
PlEngine.PlCleanup();
Console.WriteLine("finished!");
}
}
}
}
It is not running, Before run this I was add reference SwiPlCs.dll. But it shows error "FileNotFoundException was unhandled, The specified module could not be found. (Exception from HRESULT: 0x8007007E)".
So can anyone help me to fix this error?
I got this coding here

The link you've provided has full explanation of this error:
If libswipl.dll or one of its dependencies could not found you will recive an error like
System.IO.FileNotFoundException: Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E)
An other common error is:
SWI-Prolog: [FATAL ERROR:
Could not find system resources]`
Failed to release stacks
To fix this add the SWI_HOME_DIR environment variable as described in SWI-Prolog FAQ FindResources with a statment like this befor calling PlEngine.Initialize.
Environment.SetEnvironmentVariable("SWI_HOME_DIR", #"the_PATH_to_boot32.prc");
This code is commented by default, Uncomment it and provide the correct path to the the_PATH_to_boot32.prc. As described in FAQ:
Solution
On Windows, it suffices to leave libswipl.dll in the installation tree (i.e., do not copy it elsewhere) and add the bin directory of the installation tree to %PATH%.
A cross-platform and robust solution is to use putenv() to put an appropriate path into the environment before calling PL_initialise().
...;
putenv("SWI_HOME_DIR=C:\\Program Files\\swipl");
if ( PL_initialise(argc, argv) )
PL_halt(1);
...
In the final version of your application you link the saved-state to the executable (using swipl-ld or cat (Unix)) and comment the putenv() call.

Related

How to use CppSharp

I want to use CppSharp to create a C# wrapper for some classes from a C++ library which I intend to use from C# (on a 64 Bit Windows 10 system).
Unfortunately I am absolutely uncertain how to proceed. I cloned CppSharp into my filesystem and built it as described in the 'Getting started' section
https://github.com/mono/CppSharp/blob/main/docs/GettingStarted.md
I also ran all the test successfully.
From what I read in the documentation I was under the impression that to use CppSharp one has to create a C# application (for simplicity a console application), implement an abstract class from CppSharp and execute some commands from CppSharp. From
https://github.com/mono/CppSharp/issues/82
EDIT: Now I use the following code
using CppSharp;
using CppSharp.AST;
using CppSharp.Generators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CppSharpTransformer
{
class DllDemoGenerator : ILibrary
{
public static void Main(string[] args)
{
ConsoleDriver.Run(new DllDemoGenerator());
}
void Setup(Driver driver)
{
var options = driver.Options;
options.GeneratorKind = GeneratorKind.CSharp;
var module = options.AddModule("Sample");
module.IncludeDirs.Add(#"C:\Users\Boehm.J\Documents\CppSharpSamples\Sample\include");
module.Headers.Add("Sample.h");
module.LibraryDirs.Add(#"C:\Users\Boehm.J\Documents\CppSharpSamples\Sample\lib");
module.Libraries.Add("Sample.lib");
}
public void SetupPasses(Driver driver) { }
public void Preprocess(Driver driver, ASTContext ctx)
{
}
public void Postprocess(Driver driver, ASTContext ctx)
{
}
void ILibrary.Setup(Driver driver)
{
}
}
}
which is in Program.cs of my Console application I called CppSharpTransformer.
I could make it compile ok (Visual Studio 2022, Console Project with NET 6.0) by adding the following DLLs to my project:
CppSharp.AST.dll
CppSharp.CLI.dll
CppSharp.CppParser.dll
CppSharp.dll
CppSharp.Generator.dll
CppSharp.Parser.Bootstrap.dll
CppSharp.Parser.CLI.dll
CppSharp.Parser.CSharp.dll
CppSharp.Parser.dll
CppSharp.Parser.Gen.dll
CppSharp.Runtime.dll
I added them under "Dependencies (Abhängigkeiten) > Assemblys" and also as files as members of my project.
But I can not execute the application currently, as I get the runtime error:
Could not load file or assembly 'CppSharp.Parser.CLI, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null'. Das System kann die angegebene
Datei nicht finden.
(The german text says "The system can not find the specified file").
But the dll of this name is, it seems, in place. It occurs in
C:\Users\Boehm.J\Documents\work\CppSharpTransformer\CppSharpTransformer
and in
C:\Users\Boehm.J\Documents\work\CppSharpTransformer\CppSharpTransformer\bin\x64\Release\net6.0
I've just run into the same issue.
Make sure you copy the Ijwhost.dll into your application's output path.
For example like this:
<Target Name="CopyNative" AfterTargets="Build">
<Copy SourceFiles="..\CppSharp\bin\Release_x64\Ijwhost.dll" DestinationFolder="$(OutputPath)" />
</Target>

How can I add a static 'Main' method suitable for an entry point?

I am getting an error on my code that says "Error CS5001
Program does not contain a static 'Main' method suitable for an entry point"
I am coding in C# using Microsoft Visual Studio and .NET. This is my code.
using System.IO;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using System;
class projectsummer
{
[CommandMethod("OpenDrawing", CommandFlags.Session)]
public static void OpenDrawing()
{
string strFileName = "C:\\DRAFT.dwg";
DocumentCollection acDocMgr = Application.DocumentManager;
if (File.Exists(strFileName))
{
acDocMgr.Open(strFileName, false);
}
else
{
acDocMgr.MdiActiveDocument.Editor.WriteMessage("File " + strFileName +
" does not exist.");
}
}
}
I am not sure how to go about this error. Thank you!
Looking at this post and your previous question, let's try and break down what's going on.
You created a new Console application in Visual Studio. You did not tick "Do not use top level statements". This gave you a Program.cs file that was essentially empty (there was no "Main" method visible).
You erased the Hello World code given to you, and went to make a static method - the code from your previous question.
Damien_The_Unbeliever commented that based on the error, you put your method inside a "top level statement" file, and to put your method inside a class.
You wrap your method (which is still inside Program.cs) in a class, and now suddenly you get a Can't Find Entry Point error.
User Ryan Pattillo posted a great explanation of the original issue - where your method was "by itself" in the Program.cs file. You should follow their advice, but you should also ensure that this class is in its own file.
You should end up with this:
Program.cs
// this is the entire contents of the file
using ConsoleApp1;
ProjectSummer.OpenDrawing();
ProjectSummer.cs
using System.IO;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using System;
namespace ConsoleApp1
{
public class ProjectSummer
{
[CommandMethod("OpenDrawing", CommandFlags.Session)]
public static void OpenDrawing()
{
// ...
}
}
}
Change ConsoleApp1 to the name of your project.
The entry point of your application, which right now is the only file that has "top level statements", remains Program.cs, thus you fix the Can't Find Entry Point error.
Another adjustment you can make, which seeing you're new to C# might be useful, is to not use top level statements at all. Modify your Program.cs to this:
namespace ConsoleApp1
{
internal static class Program
{
// this is your program's entry point
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
ProjectSummer.OpenDrawing();
}
}
}
Change ConsoleApp1 to the name of your project.
You cannot use the AutoCAD .NET API out of process. To be able to use the AutoCAD .NET libraries, you have to build a "class library" project (DLL) and NETLOAD this DLL from a running AutoCAD process. See this topic about in-process vs out-of-process and you can start from this other one to see how to create an AutoCAD .NET project.

Unity command-line build requires UnityEditor.BuildPipeline, but builds fail for missing 'UnityEditor' reference

I am presently trying to create a batch file for a command-line build of a simple Unity project.
Current environment is:
* Windows 10
* Unity 2017.4.19f1 (Personal)
* Offline network
The project consists of just a simple scene that works fine in the UnityEditor. After failing to get a good build, I've stripped down my build script and batch file to the following:
BareBoneBuild.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
namespace Assets.BuildScripts
{
class BareBoneBuild
{
private static string windowsBuildFolderPath = "G:/dev/projects/SimpleProject";
static void PerformBuild()
{
string[] scenes = { "Assets/Scenes/DetectionTest.cs" };
BuildPipeline.BuildPlayer(scenes, windowsBuildFolderPath + "/junk.exe", BuildTarget.StandaloneWindows, BuildOptions.None);
}
}
}
BareBoneBuild.bat
title Unity Build
echo Launching Unity Build...
"C:\Program Files\Unity\Editor\Unity.exe" ^
-batchmode ^
-projectPath G:\dev\projects\SimpleProject ^
-executeMethod Assets.BuildScripts.BareBoneBuild.PerformBuild ^
-quit ^
-logFile G:\dev\projects\SimpleProject\logs\BareBoneBuild.log
echo Build Finished!
PAUSE
BareBoneBuild.log (snippet)
...
-----CompilerOutput:-stdout--exitcode: 1--compilationhadfailure: True--outfile: Temp/Assembly-CSharp.dll
Compilation failed: 1 error(s), 0 warnings
-----CompilerOutput:-stderr----------
Assets/BuildScripts/BareBoneBuild.cs(6,7): error CS0246: The type or namespace name `UnityEditor' could not be found. Are you missing an assembly reference?
-----EndCompilerOutput---------------
- Finished compile Library/ScriptAssemblies/Assembly-CSharp.dll
Assets/BuildScripts/BareBoneBuild.cs(6,7): error CS0246: The type or namespace name `UnityEditor' could not be found. Are you missing an assembly reference?**
(Filename: Assets/BuildScripts/BareBoneBuild.cs Line: 6)
DisplayProgressNotification: Build Failed
Error building Player because scripts had compiler errors
(Filename: Line: -1)
...
EVERY tutorial, blog, youtube video, forum
* https://docs.unity3d.com/2017.4/Documentation/Manual/CommandLineArguments.html
* http://jonathanpeppers.com/Blog/automating-unity3d-builds-with-fake
* https://www.youtube.com/watch?v=4J3SmhGxO1Y
* others...that I don't have the links to
I've viewed states that BuildPipeline.BuildPlayer is the way to build a project from the command-line. BuildPipeline is inside the UnityEditor library.
What am I doing wrong? I'm still new to Unity, so any obvious solution is probably correct.
Thanks in advance for any guidance!
You can't have using UnityEditor; in a build. It is stripped of.
You only need this available in an editor script and not in a build so:
Either use #if pre-processors wrapping everything using it like
#if UNITY_EDITOR
using UnityEditor;
#endif
...
#if UNITY_EDITOR
// anything using UnityEidtor e.g. the method or entire class
#endif
or in your case simply move the entire script into a folder called Editor which strippes of the entire script for a build (see Special folder names).
This is actually also mentioned - though not well explained - by your link:
Then you would need a class in your Unity project in an Editor folder such as this Android example:
or in newer Unity versions you can put it in a separate folder (with any name) and create an AssemblyDefinition and configure it so it is only compiled for the UnityEditor (see in particular Creating an assembly for Editor code)

.net C# jdbc driver connector exception

I'm trying to connect to a hyperSQL database (HSQLDB) on my local machine from a c# application in visual studio.
I've ran through the steps to create the .net JDBC driver to build the dll, and also downloading the demo console application in the "download" section from the following url: http://nikolaiklimov.de/query-java-HyperSQL-database-with-csharp/
The demo application works!! i can connect to the database and query its contents . Next I have converted the console app into a class library then call the class library to query the DB but this is where it falls over and I get initialization errors of System.TypeInitializationException. any idea why the project falls over after converting to a class library. (if i convert the class library straight back a console app it works again).
The code and connection string are:
namespace HyperSQL
{
public static class sqlconnector
{
readonly static string CONNECTION_STRING =
ConfigurationManager.ConnectionStrings["HyperSQL"].ConnectionString;
const string SQL = "SELECT * FROM meeting";
public static void getdata()
{
try
{
java.sql.DriverManager.registerDriver(new org.hsqldb.jdbcDriver());
using (java.sql.Connection conn = java.sql.DriverManager.getConnection(CONNECTION_STRING))
{
java.sql.PreparedStatement ps = conn.prepareStatement(SQL);
using (java.sql.ResultSet rs = ps.executeQuery())
{
while (rs.next())
{
Console.WriteLine($"MEETING_NO={rs.getInt("MEETING_NO")}");
Console.WriteLine("------------------");
}
}
}
}
catch (Exception ex)
{
}
Console.ReadLine();
}
}
}
jdbc:hsqldb:hsql://localhost:3458/elitedb;crypt_key=DADADADADAADDADAD;crypt_type=AES;shutdown=true;write_delay=false;user=****;password=****
Ive added a console app to my solution after the conversion to a class libary. The console app code is below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
try
{
HyperSQL.sqlconnector.getdata();
}
catch (Exception ex)
{
}
}
}
}
Here is a link to download my solution created in visual studio. It contains a console application that calls a function in a class library. The class library (HyperSQL) itself is simply converted from a console application and can be converted back. You will need a running instance of HyperSQL on your machine to be able to connect successfully.
http://eliteservicedev.azurewebsites.net/DemoHyperSQL.zip
Have you seen the error listed in the original site you posted?
If your forget to add runtime dependencies to the build folder of your
project then you can get these errors: Could not load file or
assembly 'IKVM.OpenJDK.Util, Version=8.1.5717.0, Culture=neutral,
PublicKeyToken=13235d27fcbfff58' or one of its dependencies. The
system cannot find the file specified. TypeInitializationException:
The type initializer for 'org.hsqldb.jdbc.JDBCDriver' threw an
exception: FileNotFoundException: Could not load file or assembly
'IKVM.Runtime, Version=8.1.5717.0, Culture=neutral,
PublicKeyToken=13235d27fcbfff58' or one of its dependencies. 'The
type initializer for 'sun.util.locale.provider.LocaleProviderAdapter'
threw an exception.' FileNotFoundException: Could not load file or
assembly 'IKVM.OpenJDK.Text, Version=8.1.5717.0, Culture=neutral,
PublicKeyToken=13235d27fcbfff58' or one of its dependencies. 'The
type initializer for 'org.hsqldb.HsqlDateTime' threw an exception.'
InvalidCastException: Unable to cast object of type
'java.util.PropertyResourceBundle' to type
'sun.util.resources.OpenListResourceBundle'.
***** UPDATE
With the source project i see an error, looking in the bin\debug folder i see that non all the referenced file are copied to ConsoleApp1.exe bin folder: this is the compare result:
Confronto in corso dei file consoleapp1.txt e DEMOCSHARPTHYPERSQL.TXT
***** consoleapp1.txt
ConsoleApp1.exe
ConsoleApp1.exe.config
ConsoleApp1.pdb
hsqldb.dll
HyperSQL.dll
***** DEMOCSHARPTHYPERSQL.TXT
hsqldb.dll
HyperSQL.dll
*****
***** consoleapp1.txt
IKVM.OpenJDK.Jdbc.dll
IKVM.OpenJDK.Text.dll
***** DEMOCSHARPTHYPERSQL.TXT
IKVM.OpenJDK.Jdbc.dll
IKVM.OpenJDK.Localedata.dll --> Missing in ConsoleApp1.exe folder
IKVM.OpenJDK.Text.dll
*****
If i manually copy the missing dll on ConsoleApp1.exe folder the program run correctly. I think that is a visual studio bug
Seems VS is not copying all IKVM DLLs to output folder due to not resolving they are needed. Please see this SourceForge issue and this GitHub issue, the later one with my comments.

CSCore: access violation when listening to audio session events

I'm just getting started with CSCore, and getting back to C# after a lot of C++. Here's a test program that enumerates the audio sessions of the default audio session manager, and attaches an empty event handler to each one:
using System;
using CSCore.CoreAudioAPI;
class Program
{
static void Main(string[] args)
{
using (var enumerator = new MMDeviceEnumerator())
using (var device = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia))
using (var sessionManager = AudioSessionManager2.FromMMDevice(device))
using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
{
foreach (var control in sessionEnumerator)
{
var control2 = control.QueryInterface<AudioSessionControl2>();
RegisterAudioSession(control2);
}
}
Console.WriteLine("Waiting...");
Console.ReadKey();
}
static void RegisterAudioSession(AudioSessionControl2 session)
{
if (session.Process != null)
{
var events = new AudioSessionEvents();
session.RegisterAudioSessionNotification(events);
}
}
}
I would expect to be able to change the volume of my computer while this program is running without any problems. If you try this, however, the program crashes with an access violation in native code. Here's the stack trace:
> AudioSes.dll!CLockedList<ATL::CComPtr<IAudioSessionEvents>,0,1>::ForEachEntry() Unknown
AudioSes.dll!CAudioSessionControl::OnAudioSessionEvent() Unknown
AudioSes.dll!CAudioSessionControl::CAudioSessionNotificationDelegator::OnMediaNotification(struct MEDIA_NOTIFICATION_BLOCK *) Unknown
MMDevAPI.dll!CMediaNotifications::OnMediaNotificationWorkerHandler(struct _TP_CALLBACK_INSTANCE *) Unknown
MMDevAPI.dll!CMediaNotifications::MediaNotificationWorkerHandler(struct _TP_CALLBACK_INSTANCE *,void *) Unknown
ntdll.dll!TppSimplepExecuteCallback() Unknown
ntdll.dll!TppWorkerThread() Unknown
kernel32.dll!#BaseThreadInitThunk#12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!__RtlUserThreadStart#8() Unknown
The crash does not occur if you remove the call to RegisterAudioSessionNotification.
The crash still occurs if you register a non-empty event handler.
I tried moving Console.ReadKey(); into the using block in case a necessary resource was being disposed, but the failure persisted.
I searched all over the place for an explanation and solution. There are no relevant open issues on CSCore's github page. I read somewhere that crashes in native code are often caused by incorrect signatures in wrapper assemblies. I compared all of the methods on CSCore's IAudioSessionEvents to the native IAudioSessionEvents methods (enumerated here) but found no obvious discrepancies.
This Firefox bug is the only reference I found online to this particular stack trace, and it has been resolved. Apparently it was resolved in Flash Player 19.0.0.159, but as far as I know that source isn't available for perusal.
Am I overlooking an error in my code, or is this a bug in CSCore?
Turns out this crash occurs if the target platform is 32-bit (or in my case, "Any CPU" but running in the 32-bit VS process). Switching to a 64-bit target platform fixed it for me

Categories