New (.NET Core) C++/CLI project has compile issues when definition and implementation are split - c++-cli

I created a "CLR Empty Project (.Net Core)" project using Visual Studio 2019.
I simply created a new class using the 'add class' menu option and it generated this class.
I added the function called Test in the header:
using namespace System;
public ref class Class1 {
// TODO: Add your methods for this class here.
void Test();
};
Then using visual studio's generate implementation option it created this function defenition in the .cpp file:
#include "EngineEditorLayer.h"
#include "pch.h"
void Class1::Test() { throw gcnew System::NotImplementedException(); }
When compiling it gave me this error :
error C2653: 'Class1': is not a class or namespace name
I can only resolve this error by moving the implementation to the header file.
Am I missing something? Is there a setting I have to change to enable .cpp compilation?
Is there a compiler bug that prevents me from doing this currently?

Hans Passant from the comments was right. The pch.h has to be included first.
I unfortunately never got the warning. This was my output log:
1>------ Build started: Project: EngineEditorLayer, Configuration: Debug x64 ------
1>EngineEditorLayer.cpp
1>E:\Other Projects\PixEngine\EngineEditorLayer\EngineEditorLayer.cpp(7,18): error C2653: 'Class1': is not a class or namespace name
1>Done building project "EngineEditorLayer.vcxproj" -- FAILED.

Related

Read Config From Another Project - Log4Net ASP.NET Core 3.1

I am trying to write a class library that uses log4net that looks something like this:
public class Logging
{
private ILog log4netLogger = null;
public Logging(Type type)
{
XmlDocument log4netConfig = new XmlDocument();
log4netConfig.Load(File.OpenRead("log4net.config"));
var repo = LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));
XmlConfigurator.Configure(repo, log4netConfig["log4net"]);
log4netLogger = LogManager.GetLogger(type);
}
public void Debug(string message)
{
log4netLogger(message);
}
public void Info(string message)
{
log4netLogger(message);
}
}
However, the xml configuration is in my test console app in C:\....\TestLogging\TestLog4Net\bin\Debug\netcoreapp3.1. I actually started with this console app to test log4net but I have moved all my code from the main method of Program.cs to the Logging.cs constructor, but I think the LogManager will not be able to find this now.
Is this at all possible?
I think it is possible. To use the log4net in the class library, you have to install the log4net package in the class library, then, you could add the class library reference in the console application and use the class library method. But, as you said, the log4net.config file should be in the console application netcoreapp3.1 folder, otherwise, the class library will not find the log4net.config file:

What is causing the error that swagger is already in the route collection for Web API 2?

I installed Swagger in my ASP.Net MVC Core project and it is documenting my API beautifully.
My co-worker asked me to install it in a full framework 4.6.1 project so I've done the following.
In Package Console Manager run:
Install-Package Swashbuckle
To get your Test Web API controller working:
1) Comment this out in the WebApi.config:
// config.SuppressDefaultHostAuthentication();
// config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
Now this URL:
http://localhost:33515/api/Test
brings back XML:
<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<string>value1</string>
<string>value2</string>
</ArrayOfstring>
In Global.asax Register() I call:
SwaggerConfig.Register();
In AppStart.Swagger.Config Register() I put:
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1.0", "HRSA CHAFS");
c.IncludeXmlComments(GetXmlCommentsPath());
})
.EnableSwaggerUi(c =>
{});
}
private static string GetXmlCommentsPath()
{
var path = String.Format(#"{0}bin\Services.XML", AppDomain.CurrentDomain.BaseDirectory);
return path;
}
}
Now I get this error:
"A route named 'swagger_docsswagger/docs/{apiVersion}' is already in the route collection. Route names must be unique."
I've been stuck on this for hours.
How do you get rid of this?
This can happen when you re-name your .NET assembly. A DLL with the previous assembly name will be present in your bin folder. This causes the swagger error.
Delete your bin folder and re-build your solution.
This resolves the swagger error.
Swagger config uses pre-application start hook, so you don't need to call SwaggerConfig.Register() explicitly. Otherwise Register method is called twice.
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
in my case i added another project as refrence and that other project has swagger too.
i remove that refrence and move needed code to new project.
I solved the problem by deleting the SwaggerConfig.cs file from the App_Start folder as I had already created it manually.
Take a look at this link, here also has more useful information:
A route named 'DefaultApi' is already in the route collection error
In my experience the error occurs when you add reference to another project and that project is a service and it occurs on the SwaggerConfig of the referenced project. Removing project reference usually solve the problem, if you need to share classes I suggest you to create a specific project as Class Library and add its reference to both your services

What does compilationOptions.emitEntryPoint mean?

Just installed the rc1 tools and created a new web project to see what has changed in the template.
I noticed that project.json now contains:
"compilationOptions": {
"emitEntryPoint": true
}
But it's unclear what this does.
Does anyone have an idea?
As mentioned below: It looks like it is a flag to the compiler to indicate that the project is a console application vs. a library (namely: a console application must contain public static void Main())
You can see from the source here.
In the new RC1 default web application template, you'll notice at the bottom of Startup.cs there is a new expression bodied method that acts as the entry point:
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
If you remove this method then perform a build (dnu build) you will get an error:
error CS5001: Program does not contain a static 'Main' method suitable for an entry point
However, if you change the emitEntryPoint flag to false and attempt to build again, it will succeed. This is because it is creating a library instead of a console app.
I see this in the source;
var outputKind = compilerOptions.EmitEntryPoint.GetValueOrDefault() ?
OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary;
Looks like it tells the compiler whether to create a Console Application or a Library.
Additionaly, if you create a new Class Library (Package) and Console Application (Package) in VS2015 you'll see that project.json for the Console Application includes the following, while the Class Library does not;
"compilationOptions": {
"emitEntryPoint": true
}

MonoMac / Xamarin.Mac binding simple dylib not working

I'm trying to bind some native code for use in MonoMac / Xamarin.Mac, but I'm not sure where I'm going wrong. I create a simple dylib to test with:
nativelibrary.h:
- (NSString *)echo:(NSString *)message;
I know that my library is fine, because I reference it and use it in an Objective-C / Cocoa application.
Next, I try to generate the initial binding file using parse.exe:
mono parse.exe [path...]/nativelibrary.h
Problem #1
No 'gen.cs' file is generated as per Miguel's guide
Problem #2
Parse.exe does actually output something to the console, although it's missing my only method?
[BaseType (typeof (NSObject))]
interface nativelibrary {
}
Regardless, I go ahead and make my own gen.cs file, filling in the missing method manually:
gen.cs:
using MonoMac.Foundation;
namespace ManagedConsumer
{
[BaseType (typeof (NSObject))]
interface Binding
{
[Export ("echo:")]
string Echo(string message);
// I also tried like this:
// NSString Echo(NSString message);
}
}
Next, I try to create my binding DLL using bmac.exe:
mono bmac.exe -o="dynamiclibrary.dll" -d="MONOMAC" -r="System.Drawing" -v [path].../gen.cs
This spits out a .dll which I reference in my MonoMac project.
Finally, I add the .dylib itself to my MonoMac project, and specify the 'content' build action. I verify that the .dylib is copied to the 'Resources' directory of my bundle.
I can instantiate an instance of my binding object no problem:
Binding b = new Binding();
Console.WriteLine(b.ToString());
Problem 3 However, trying to call my method:
Binding b = new Binding();
var result = b.Echo((NSString)"Hello, world");
results in an unmanaged crash:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000000bf74bffc
I have seen in another question, that we need to force the .dylib to load. So I try to insert this line into my main.cs, before Application.Init() is called:
Dlfcn.dlopen ("nativelibrary.dylib", 0);
But I get the same crash. Since the call to dlopen returns 0 rather than a valid pointer, I assume that the issue is in loading my dynamic library. I also tried to use the attribute:
[assembly:MonoMac.RequiredFramework("nativelibrary.dylib")]
But that only gets me:
System.Exception: Unable to load required framework: 'nativelibrary.dylib'
What am I doing wrong?
After a lot of trial and error, I was able to make this work. Two changes:
In my homebrew gen.cs file, the interface name needed to match the name of my native class, i.e.
nativelibrary.h
#interface nativelibrary : NSObject
- (NSString *)echo:(NSString *)message;
gen.cs
using MonoMac.Foundation;
namespace ManagedConsumer
{
[BaseType (typeof (NSObject))]
interface nativelibrary
{
[Export ("echo:")]
string Echo(string message);
}
}
Secondly, it seems there was something about my native library itself that means it couldn't be opened with dlopen. I think the problem is that the XCode 'library' project defaults to x64, and it appears only x86 will work.
I compiled it from the command line instead, like so:
gcc -arch i386 -framework Cocoa -o nativelibrary.o -c [path...]/nativelibrary.m
Then built my library:
libtool -dynamic -flat_namespace -lSystem -undefined suppress -macosx_version_min 10.6 -install_name $CURRENT_DIR/nativelibrary.dylib -o nativelibrary.dylib nativelibrary.o
And it now works.

No source available when debuggin ninject

I have same the problem as here No Source Available Error With Ninject When Debugging Code
Checking "Tools/Options/Debug/Just my code" makes absolutely no difference at all.
The error appears when debugger steps out from class below:
class TestModule : Ninject.Modules.NinjectModule {
public override void Load() {
Bind<IWeapon>().To<Sword>();
Bind<IWeapon>().To<Dagger>();
}
}
I installed Ninject yesterday using 'Add library package reference' in VS2010