Can I add C++ DLL in a ASP MVC application - c++

I am trying to add a reference to a DLL built using C++ in ASP.Net MVC 5 application.
I want to call functions in DLL from the app.

Yes you can. The key here is "platform invoke".
You need to create a class holding the DLL methods (Win32 in the sample)
You need to define the prototypes/signatures of the DLL methods, using the DllImport annotation
Now you can call those methods
This sample is taken from the Microsoft documentation:
using System;
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr MessageBox(int hWnd, String text,
String caption, uint type);
}
public class HelloWorld {
public static void Main() {
Win32.MessageBox(0, "Hello World", "Platform Invoke Sample", 0);
}
}

Yes, any native or unmanaged DLL can be used with ASP MVC applications. The builds should be targeting the same Platform. If a C++ DLL has been built for x64 platform, then the application(web/console) importing it should also be built for the same configuration.
See the post from #bdongus for importing using DllImport. Also the servers should run on the same platform.

Related

Use NetCDF4-C in Unity

this is my first time posting (after lurking for years).
A project I will be tackling is to use NetCDF4 (.nc) files in Unity on Windows. I will be using Unity 5.4.0f3 and Windows 10, and I have developed in Unity before and am familiar with C# and JavaScript, but NetCDF only has C, Java, and Fortran APIs, although there are wrappers in Python, C++, and others (source: https://www.unidata.ucar.edu/publications/factsheets/current/factsheet_netcdf.pdf).
So my specific question is how do I call NetCDF4-C functions (nc_get_vara_float(), nc_open, etc) in C# for use in Unity?
What I've tried so far:
To start, I googled specifically for NetCDF4-C + Unity tutorials/attempts, but did not find anything, so instead I have been looking into the compatibility of calling C functions from C#. I am currently working on a project on Linux with NetCDF4-C and written custom wrapper functions for the netcdf.h functions, so I was hoping I could reuse my code there.
I attempted to follow this SO post (Is it possible to call a C function from C#.Net) but get an error in Unity when trying to Play: "DllNotFoundException: test.so" (my file was named "test.c"). From the comments, it seems Linux uses .so files but Windows uses .dll, and I was not sure how to generate a .dll of a C file.
I looked up another post on that (How to write a DLL file in C?) and downloaded Visual Studio to follow along. While VS was downloading, I looked up how to use GCC to compile (Creating a DLL in GCC or Cygwin?), and used the Bash subsystem ("Bash on Ubuntu on Windows" terminal) but got a handful of errors that indicated the code from the previous link (2nd SO link in this post) were for C++, so I stopped working with GCC.
Once VS finished installing, I went back to trying to use VS to create the .dll, and attempted to combine the solutions from both SO posts (1 and 2) so that I would be able to use the .dll file containing C code in Unity, but to no avail: I get the same error but just with a different extension (and different name on purpose): "DllNotFoundException: Win32Project1.dll".
The code I have is as follows:
test.cs (used in Unity and attaches to a Component):
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class test : MonoBehaviour {
[DllImport("Win32Project1.dll", EntryPoint="DisplayHelloFromMyDLL")]
public static extern void DisplayHelloFromMyDLL ();
// Use this for initialization
void Start () {
DisplayHelloFromMyDLL();
}
// Update is called once per frame
void Update () {
}
}
Win32Project1.dll (created and built in Visual Studio):
#include <stdio.h>
extern "C"
{
__declspec(dllexport) void DisplayHelloFromMyDLL()
{
printf("Hello DLL.\n");
}
}

Win32 Application, Call custom class method before calling Windows stuff

Context:
I am trying to create a class that is the first to be called in a WIN 32 application... That class has a Setup method... I will then invoke the Windows class taken from here:
https://msdn.microsoft.com/en-us/library/bb384843.aspx
header
class OSWindows : IOS
{
public:
void Setup() override;
};
cpp
#include "OSWindows.h"
void OSWindows::Setup()
{
// Calls the windows stuff...
}
Question
How do i stop the Win32 application from automatically running their WinMain method...
Note:
I'm trying to make a portable application... and thus don't want the app to just simply have the app call the windows stuff first.
In Visual Studio you can change the entry point at
Project Properties -> Configuration Properties -> Linker -> System -> SubSystem
If you want it to be int main change it to Console (/SUBSYSTEM:CONSOLE).
The default for Win32 Applications is Windows (/SUBSYSTEM:WINDOWS) which is WinMain.

LoadLibrary fails with error 203: The system could not find the environment option that was entered

I created a c# class library. I want to load this .dll in my win32 console application, because I have exported one function from the c# class library to unmanaged code and I don't know of any other way to call that function now.
But LoadLibraryA is giving me that error, what can it mean? Googling didn't help me at all.
Used this to export the function to unmanaged:
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports#TOC-C-:
EDIT: Here is the code, sorry I didn't include it at first because it's as barebones as it gets:
using System;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;
namespace ManagedLibrary
{
public class Test
{
[DllExport(CallingConvention = CallingConvention.Cdecl)]
public static void test()
{
Console.WriteLine("HI");
}
}
}
Looks like the unmanaged exports nuget tool doesn't work for me, the .dll loading errors were mostly obscure and unrelated as it seems (although I did switch to my home computer now)
After I have manually added the exports IL statement as described here:How do you export a method in a CIL DLL so that a native program can call it? I was able to call the C# code just fine.

Native dll built with /CLR flag containing a managed class

I have a old native MFC/c++ dll I have managed to get it compiled with /CLR flag.
Now I have added a managed C++/CLI class to the dll within a namaspace.
The header file is below, and the cpp file only has #include for the header file.
The native dll is a huge dll project with lot of un managed code, but it has only one managed c++ class like below.
When I add that dll as a reference to a .net winforms project I don't see that namespace / class, in the object browser,
and I get compile error for not finding the namespace "ShashiTest"
I am using Visual studio 2008.
Native dlls in mixed mode can not be added as reference to a managed project ?
Or am I missing something
Please help.
#pragma once
#using<mscorlib.dll>
#using<system.windows.forms.dll>
// Class derived from Forms
using namespace System::Windows::Forms;
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Diagnostics;
using namespace System::Windows::Forms;
namespace ShashiTest {
/// <summary>
/// Summary for test
/// </summary>
public ref class test
{
public:
test(void)
{
};
void ShowMessage()
{
MessageBox::Show("Hello World");
}
};
}
When I simplified my problem..I created a fresh MFC dll and added a manged C++ class to it (same class as above) . Compiled with /CLR flag.
When I add this dll to winforms project and run it i get
System.BadImageFormatException. Any clue ?
However I see the class and the name space and winform project compiles fine unlike the problem I have the above.
System.BadImageFormatException is usually caused by having an AnyCPU .NET application reference a DLL containing 32-bit native code. You get an error when running on a 64-bit platform, because the AnyCPU application runs as 64-bit, and can't load the DLL. The fix for this is (easy) to mark the application as x86-only or (hard) to provide both 32-bit and 64-bit versions of all DLLs containing native code.
Of course, you could have some other problem. Checking your DLL with Red Gate Reflector as suggested by #cdleonard in the comments is a great next step. Or ILSpy, which is free.

Creating CMFCDesktopAlertWnd Control in Visual C++

MSDN contains an example for creating a desktop alert window:
http://msdn.microsoft.com/en-us/library/bb983515.aspx
The sample code starts with the following declaration.
CMFCDesktopAlertWnd* pPopup = new CMFCDesktopAlertWnd;
When I use it in my code, the compiler complains
'CMFCDesktopAlertWnd' : no appropriate default constructor available
This is the complete source code of my application.
(I created an empty Win32 project in Visual Studio and set
the Use MFC in a Shared DLL option on the Property | General page.)
#include <afxwin.h>
#include <afxDesktopAlertDialog.h>
class Notifier : public CWinApp
{
public:
virtual BOOL InitInstance();
};
BOOL Notifier::InitInstance()
{
CMFCDesktopAlertWnd* pPopup = new CMFCDesktopAlertWnd;
return TRUE;
}
Notifier myApp;
What am I doing wrong?
The effect is the same in VS Express 2008 and the full version of VS 2010.
Are you using VS 2008 SP1? (The service pack is important)
Are you including the proper headers in stdafx.h? More specifically, you need
#include < afxext.h >
#include < afxcontrolbars.h >
to be able to use MFC Next (feature pack) classes.
It won't work on VS Express anyway because that doesn't include MFC.