Access C# static class from a C++ DLL - c#

I've been tasked with writing a new interface to a legacy C++ DLL I don't have the source code for, which - for reasons beyond me - accesses a global class in the legacy application directly.
From the application, it's something like:
extern Interface *App;
...
Interface App*; // A pointer to our interface class.
Then, from the legacy DLL:
if( App->GetStatus() ) return false;
The Interface class that App refers to is quite trivial to rewrite in C#, but how can I make it the equivalent of extern so that the legacy C++ DLL can access it?
Thanks!

You could try using Robert Giesecke's "UnmanagedExports" nuget package to achieve this functionality like so:
class Test
{
[DllExport("add", CallingConvention = CallingConvention.Cdecl)]
public static int TestExport(int left, int right)
{
return left + right;
}
}
However:
a) I believe this only works for methods, not classes and
b) the reason there isn't a native way to export a DLL in C# is because that the calling application must have the .NET framework loaded in order to access that entry point. This also applies to the UnmanagedExports nuget package that I linked to above.
You can hack your way around this by getting your C++ app to load mono before calling the C# app, but it doesn't sound like this is possible in your case.
(Also, UnmanagedExports will only work if you explicitly set a build target in your project's properties - eg. x86)

Related

Parameters are incorrect after passing from C# to unmanaged dll

Have been trying all day and searching various sources but can't find a solution. I am calling an imported unmanaged dll function from c#.
C++ class looks like:
class MyModule
{
public:
MYMODULEDLL_API int __cdecl Init(int);
...
Defined in C# like this:
[DllImport("MyModule_x64.dll", EntryPoint =
"?Init#MyModule##QEAAHH#Z", CallingConvention = CallingConvention.Cdecl)]
public static extern int Init(int len);
And calling like this:
Init(configFileName.Length);
I can see in the debugger that the proper function in the dll is being called, but the passed parameter is corrupted showing a completely different value than what was passed. This is happening for string parameters as well. Is there anyway to troubleshoot the marshalling of parameters between managed and unmanaged code?
You can`t use C++ classes using DLLImport or PINVOKE, because it is suitable only for C style functions.
If you want to use C++ class in C#, you need to go with C++/CLI. You can create an unmanaged dll in native C++ and then create a simple C++/CLI wrapper which calls methods from native dll. After that you can simply add a C++/CLI managed dll to the project and use it as C# class without any DllImports and PINVOKEs. It will be a very flexible soltuion which is easy to expand. On MSDN you can find examples how to use C++/CLI.

C# DLL Missing Public Functions

I am attempting to write a DLL using the C# .NET Framework 2.0. Everything compiles okay, but when I try to access the DLL from my application, it fails when attempting to get the procedure address. So, I oped the DLL in Dependency Walker, and all of my public functions are missing!
My DLL, so far, is fairly straightforward:
namespace MyDll_Namespace
{
public class MyDllClass
{
public static int Func1( /* params */ ) { /* ... */ }
public static int Func2( /* params */ ) { /* ... */ }
public static int Func3( /* params */ ) { /* ... */ }
public static int Func4( /* params */ ) { /* ... */ }
}
}
There's not much else, just a few constants and delegates defined inside the class, as well as outside the class in the namespace. Any thoughts or suggestions would be much appreciated. Thanks.
Dependency walker is for win32 DLLs (which is native code), not .NET assemblies (which is managed code). It won't find methods in an arbitrary class (even if they are static). If you need to call managed code from native code, there are ways of doing that, but it's not pretty.
If you want to use your dll from managed code, it's a lot easier. Check out System.Assembly and Activator.
An example of this:
var assembly = Assembly.LoadFile(#"\path\to\your.dll");
var mydllclass_type = assembly.GetType("MyDllClass");
var instance = Activator.CreateInstance(mydllclass_type);
The instance will be an object. To call the methods, you need to use reflection, because the interface is not known at compile-time.
If you are creating a plugin system, the best way is to have a common interface or abstract base for all plugins, and have that referenced by your program. Those third parties who implement a plugin, will also reference this contract. In this case, the last line changes a bit:
var instance = (IMyDllClass)Activator.CreateInstance(mydllclass_type);
Now you can use the methods like in a regularly constructed object.
Part of the problem here is that dependency walker is a tool for native applications. It doesn't understand managed code and hence won't display any of the managed types + methods that you've defined.
I'm confused by this line in your question
when I try to access the DLL from my application, it fails when attempting to get the procedure address
This sounds a bit like an error I would see in a native application, not a managed one. Are you trying to access the C# code from a native application? If so this can only be done via COM magic and not via direct calling. Can you explain in more detail what is going on here?
Try .net Reflector to see exactly what's inside your built DLL (in order to make sure everything is the way it is supposed to).
Also make sure you're in release mode while building your DLL before referencing it... I don't know if it's going to change anything, but it worths the try =)
You need to add a reference to your dll and the runtime will automatically allow you to call your function. Here is a little tutorial on writing a .net class library.
I decided to write my DLLs in C++. However, here is a bunch of useful information I found for using managed code from unmanaged code:
Is it possible to use a DLL created using C# in an unmanaged VC++ application?
How do I call C++/CLI (.NET) DLLs from standard, unmanaged non-.NET applications?
Using managed code in an unmanaged application
Using Managed Components from Unmanaged Code
An Overview of Managed/Unmanaged Code Interoperability
Unmanaged Exports
Calling Managed .NET C# COM Objects from Unmanaged C++ Code
All-In-One Code Framework
CLR Hosting APIs
How To: Migrate to /clr
How to call a managed DLL from native Visual C++ code in Visual Studio.NET or in Visual Studio 2005

How can i use a C# dll in a Win32 C++ project?

I am working on a solution, most of its core engine is developed as Win32 C++ (and is Platform independent and is also used on OS X), some time ago we needed to call C++ dll's of core engine from C# and I was able to Load main solution's DLL in C# (by the help of some threads here on SO). but now we have certain things implemented in Managed C# dll and need to use it in Win32 C++ project? (and just function definitions and dll are provided)
You can create a managed C++ interop DLL to act as a wrapper around the C# library.
Most tutorials on managed C++ unfortunately only explain how to wrap unmanaged C++ for use in C#. But it can work the other way also.
Define an abstract interface class in your native C++ code, then create a concrete subclass inside the managed C++ DLL. Call into your C# objects in the method implementations.
Finally, export a factory function that will instantiate the implementation class and return a base-class pointer that your native code can use.
Here's a quick example:
First, define the class interface in your native DLL.
interopclassbase.h
class InteropClassBase
{
public:
virtual void doStuff() = 0;
virtual int getValue() = 0;
virtual void getString(CString* outStr) = 0;
};
Now you need to create a C++/CLI DLL that will allow you to mix native and managed code in a single assembly. Add a new C++ project to your solution, and in the project configuration set the "Common Language Runtime Support" option to Mixed (/clr).
Once you've added a reference to your C# library (which we'll call ManagedLibrary) we can implement the interop class:
interopclass.cpp
#include "interopclassbase.h"
#include <vcclr.h>
public class InteropClass : public InteropClassBase
{
protected:
gcroot<ManagedLibrary::ManagedObject^> m_managedObject;
public:
InteropClass()
{
m_managedObject = gcnew ManagedLibrary::ManagedObject();
}
virtual void doStuff()
{
m_managedObject->doStuff();
}
virtual int getValue()
{
return m_managedObject->getValue();
}
virtual void getString(CString* pOutStr)
{
System::String^ managedString = m_managedObject->getString();
CString nativeString(managedString); // overloaded CString constructor
if (pOutStr) *pOutStr = nativeString;
}
};
__declspec(dllexport) InteropClassBase* getImplementationPointer()
{
return new InteropClass();
}
Now you just need to load the interop DLL from your native project and call the exported function.
One solution is COM Interop. Possibly the only solution. It a big topic. There's a big fat blue book at work I use. Hundreds of pages of nothing but COM Interop.
The short version is that you label some classes and interfaces in the managed side, and have interop assemblies created which look like COM dlls, but are really proxies to the managed assemblies. The interop assemblies are registered like COM dlls and off you go.
MSDN has a lot of information about it.
This is probably a good starting spot.
"Exposing .NET Framework Components to COM"
http://msdn.microsoft.com/en-us/library/aa720072%28VS.71%29.aspx
It can be surprisingly easy, but try to keep it simple.
To create a managed object and call methods on it you need to have the CLR running in your C++ process.
Under windows you can host the CLR by referencing mscoree.dll and hosting the CLR in process.
http://msdn.microsoft.com/en-us/magazine/cc163567.aspx
http://msdn.microsoft.com/en-us/library/ms230997.aspx
For Mono, you can embed the Mono runtime within your C++ application.
http://www.mono-project.com/Embedding_Mono

How to bind c++ dll to my C# program - winCE

i need to bind C++ dll to my C# WinCE program. (scanner dll)
how i can do it ?
thank's in advance
You need to use Interop to call into unmanaged code.
using System.Runtime.InteropServices; // DllImport
public class Win32 {
[DllImport("User32.Dll")]
public static extern void SetWindowText(int h, String s);
}
Here is an article that discusses the topic in detail (also where the code is sourced from).
http://msdn.microsoft.com/en-us/magazine/cc301501.aspx
An alternative to InterOp is to write a C++ DLL using CLR extensions which acts as a wrapper to the traditional C++ DLL. This gives you a chance to handle unusual types, e.g. custom structures or classes, if Marshaling isn't going to work. (According to MSDN you can extend the Marshaling support (http://msdn.microsoft.com/en-us/library/bb531313.aspx) but I haven't tried this personally, and depending on what you're doing it might be a lot of work).
For example if you want to access a DLL which exports a class, you can have a wrapper DLL which owns an instance of the C++ class and defines a .NET class which maps onto the C++ class. For example, here's a snippet from a C++/CLR DLL which we use to make one of our old C++ DLLs available in .NET:
// This is the constructor for the CLR (managed) object
FileInf::FileInf()
{
// Create the C++ (unmanaged) object
m_pFileInf = gcnew DILib::FileInf();
}
// This is a managed interface which replicates the old
// unmanaged functionality
bool FileInf::IsDirectory()
{
return m_pFileInf->IsDirectory();
}
I'd say if InterOp works then stick with it, but I'm not sure if it's the best way to solve every C++ / .NET interfacing problem, and this is an alternative.

Calling C# (.NET) APIs from C

To invoke a C API from C# I would use P/Invoke. But if I were to do the reverse, call .NET APIs from C, how would I go about it?
If you really want to do it all through C APIs and do an end run around COM and C++ you could do the following. But first figure out if it's truly necessary! I suspect in most cases it won't be.
Step 1. Create the C# .Net assembly you wish to call.
Step 2. Create a mixed mode CLI/C++ assembly with extern "C" functions exported. Have this assembly call the C$ assembly.
Step 3. Create your C application that calls the exported C style functions from the DLL made in step 2.
Things to consider.
A. Is there an actual NEED to have a C (versus C++/COM) app directly call a .Net assembly?
In other words, why not use C++ and COM to COM exported .Net methods if you really must have a mixed (.Net and non-.Net) application/system?
B. Will the APIs you write be wrappers on classes? If so, how will you manage their life times? (e.g. Will you create/use handles? How will you manage their relationships to the actual gc objects...etc)
C. Strings. These are handled very different between C and .Net. Make sure you're familiar with their differences and how to properly send strings across these boundaries...Hint: CString is your friend.
There is solution that can avoid using COM or C++\CLI. See here: Calling A .NET Managed Method from Native Code
you can turn c# code into COM, or use C++\CLI.
Here is a solution. It implements [DllExport] attribute
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
So one can do something like this to call managed code from unmanaged code:
C# code
class Test
{
[DllExport("add", CallingConvention = CallingConvention.StdCall)]
public static int Add(int left, int right)
{
return left + right;
}
}
C code
int main()
{
int z = add(5,10);
printf("The solution is found!!! Z is %i",z);
return 0;
}

Categories