Using C++ Class Dll in C# Application

Using C++ Class DLL in C# Application

Simple way assuming class Foo:

  1. Create a C++/CLI project, call this FooWrapper.
  2. Make FooWrapper depend on the unmanaged dll (however you normally would).
  3. Create a managed class ManagedFoo which contains a single private instance field of type Foo*.
  4. provide public wrapping functions in ManagedFoo which forward on to the underlying instance field.
  5. Optionally (though recommended):

    • convert parameters from .net idioms (strings and the like) to C++ idioms (std::string or char*)
    • catch unmanaged exceptions and throw managed ones instead

Then you make your c# code depend on the FooWrapper project/dll and ensure that the unmanaged dll is properly deployed with it, how that is done depends on the unmanaged dll but in the same directory is normally sufficient.

If the functions do not rely on instances of the class then even simpler is P/Invoke

using a class defined in a c++ dll in c# code

There is no way to directly use a C++ class in C# code. You can use PInvoke in an indirect fashion to access your type.

The basic pattern is that for every member function in class Foo, create an associated non-member function which calls into the member function.

class Foo {
public:
int Bar();
};
extern "C" Foo* Foo_Create() { return new Foo(); }
extern "C" int Foo_Bar(Foo* pFoo) { return pFoo->Bar(); }
extern "C" void Foo_Delete(Foo* pFoo) { delete pFoo; }

Now it's a matter of PInvoking these methods into your C# code

[DllImport("Foo.dll")]
public static extern IntPtr Foo_Create();

[DllImport("Foo.dll")]
public static extern int Foo_Bar(IntPtr value);

[DllImport("Foo.dll")]
public static extern void Foo_Delete(IntPtr value);

The downside is you'll have an awkward IntPtr to pass around but it's a somewhat simple matter to create a C# wrapper class around this pointer to create a more usable model.

Even if you don't own this code, you can create another DLL which wraps the original DLL and provides a small PInvoke layer.

Call c++ DLL from C# application

Thanks for the answers.
I resolved the issue by making one extra class(Wrapper class) that contains the managed code. This wrapper class is called by the c# classes in the same way as I mentioned in the question. This wrapper class than call the c++ class and return the result to the UI.

Importing a class from a c# dll into a c++ app

I normally do this kind of stuff by creating a static C++ CLR Wrapper Lib.

These are the steps I'm normally using (although I don't use it very often):

Here minimal example with using Visual Studio:

1. Create managed C# .NET library Project

Let name it HelloLibManaged
with one file Hello.cs and following content:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloLibManaged
{
public class Hello
{
public void Print()
{
System.Console.WriteLine("Hello from Managed Lib");
}
}
}

Build this lib with x86 or x64 , just dont Any CPU

2. Create a new C++ CLR static lib project within same solution.
Let's name it HelloLibCpp

  • Add a reference to HelloLibManaged project via Project->Add Reference

  • Remove automatic created existing .h/.cpp files from Project, and create these 2 files:

HelloUnmanaged.h

#pragma once

namespace hello_managed {

class Hello
{
public:
void Print();
};
}

and

HelloUnmanaged.cpp:

#include "HelloUnmanaged.h"

namespace hello_managed
{

void Hello::Print()
{
HelloLibManaged::Hello^ hello = gcnew HelloLibManaged::Hello();
hello->Print();
}

}

Und Project Properties -> General specify static lib.
In the Build settings specify x86 / x64 - use the same build type as building Managed lib from Step 1.

Now you can build the dll and use it in your other unmanaged C++ projects.

For more advanced stuff, like return types and methods with parameters you have to do Type-Marshalling between managed/unmanaged code. There are many resources online with more information about Type-Conversion between managed/unmanaged code. Keyword: Marshaling.

How do I DllExport a C++ Class for use in a C# Application

C# cannot directly import C++ classes (which are effectively name-mangled C interfaces).

Your options are exposing the class via COM, creating a managed wrapper using C++/CLI or exposing a C-style interface. I would recommend the managed wrapper, since this is easiest and will give the best type safety.

A C-style interface would look something like this (warning: untested code):

extern "C" __declspec(dllexport)
void* CExampleExport_New(int param1, double param2)
{
return new CExampleExport(param1, param2);
}

extern "C" __declspec(dllexport)
int CExampleExport_ReadValue(void* this, int param)
{
return ((CExampleExport*)this)->ReadValue(param)
}

A C++/CLI-style wrapper would look like this (warning: untested code):

ref class ExampleExport
{
private:
CExampleExport* impl;
public:
ExampleExport(int param1, double param2)
{
impl = new CExampleExport(param1, param2);
}

int ReadValue(int param)
{
return impl->ReadValue(param);
}

~ExampleExport()
{
delete impl;
}
};

Using C dll in C#

You can use PInvoke

Platform Invocation Services (PInvoke)
allows managed code to call unmanaged
functions that are implemented in a
DLL.

Here is a great tutorial by the NAG (Numerical Algorithms Group) group

Is it possible to call a C function from C#.Net

The example will be, for Linux:

1) Create a C file, libtest.c with this content:

#include <stdio.h>

void print(const char *message)
{
printf("%s\\n", message);
}

That’s a simple pseudo-wrapper for printf. But represents any C function in the library you want to call. If you have a C++ function don’t forget to put extern C to avoid mangling the name.

2) create the C# file

using System;

using System.Runtime.InteropServices;

public class Tester
{
[DllImport("libtest.so", EntryPoint="print")]

static extern void print(string message);

public static void Main(string[] args)
{

print("Hello World C# => C++");
}
}

3) Unless you have the library libtest.so in a standard library path like “/usr/lib”, you are likely to see a System.DllNotFoundException, to fix this you can move your libtest.so to /usr/lib, or better yet, just add your CWD to the library path: export LD_LIBRARY_PATH=pwd

credits from here

EDIT

For Windows, it's not much different.
Taking an example from here, you only have yo enclose in your *.cpp file your method with extern "C"
Something like

extern "C"
{
//Note: must use __declspec(dllexport) to make (export) methods as 'public'
__declspec(dllexport) void DoSomethingInC(unsigned short int ExampleParam, unsigned char AnotherExampleParam)
{
printf("You called method DoSomethingInC(), You passed in %d and %c\n\r", ExampleParam, AnotherExampleParam);
}
}//End 'extern "C"' to prevent name mangling

then, compile, and in your C# file do

[DllImport("C_DLL_with_Csharp.dll", EntryPoint="DoSomethingInC")]

public static extern void DoSomethingInC(ushort ExampleParam, char AnotherExampleParam);

and then just use it:

using System;

using System.Runtime.InteropServices;

public class Tester
{
[DllImport("C_DLL_with_Csharp.dll", EntryPoint="DoSomethingInC")]

public static extern void DoSomethingInC(ushort ExampleParam, char AnotherExampleParam);

public static void Main(string[] args)
{
ushort var1 = 2;
char var2 = '';
DoSomethingInC(var1, var2);
}
}


Related Topics



Leave a reply



Submit