What would be a common strategy for using DLLs coded in native C++ in C#? I'm not really finding much good information about it, other than writing the DLL in C.

Dani AI

Generated

A few practical ways to consume a native C++ DLL from C#, and how to pick between them.

As asked, and as and started to show, the core decision is whether you can change the native code and how rich the API needs to be. If you control the native build you can choose a bridging strategy; if not, you are constrained by what that DLL already exposes.

Options and tradeoffs:

  • C-style exports + P/Invoke: simplest for small, function-based APIs and the most portable across CLR hosts. Best when the boundary uses plain data (POD) and clear allocator/free rules. Avoid passing STL or C++ objects directly.
  • Mixed-mode managed wrapper (C++/CLI): easiest when you need full object semantics and automatic type conversion between C++ and .NET. It reduces marathon marshaling code but ties you to a mixed assembly and platform/CLR decisions.
  • COM interop: useful when COM is already present or when language-neutral object semantics are needed.
  • Binding generators (SWIG, CppSharp): useful to automate large APIs but add a generation step and learning curve.

Checks and common pitfalls to avoid:

  • Match calling conventions and process bitness (x86 vs x64) exactly.
  • Be explicit about memory ownership: provide native free functions rather than letting managed code free foreign heap allocations.
  • Do not let native exceptions unwind into managed code—catch and convert to error codes/HRESULTs at the boundary.
  • Prefer blittable structs or explicit marshaling for strings/arrays; pin delegates used as callbacks so the GC cannot collect them.
  • Deployment: place native DLLs where the process loader can find them (same folder, PATH, or explicit loader logic).

Quick rule of thumb: if you control native sources and need rich object mapping, C++/CLI speeds development; if you need portability or minimal surface area, expose a small C-style API and P/Invoke.

Recommended Answers

All 4 Replies

Here is a Microsoft article you will want to study. I'm not sure that C# can access DLLs written by non-.NET languages.

I can use a function in a DLL written in C with C#.

DLLs written in C++ can not be used by non-c++ languages unless you make the functions look like C functions by adding extern "C" to them, which prevents the compiler from mangling function names. In otherwords you will have to write C wrapper functions around the c++ code in the DLL.

AD is right, because of name-mangling in C++ (and ABI), you have to wrap all your C++ code into a C API (C functions). For example, say I wanted to "export" the following class from a DLL:

class Foo {
  private:
    double value;
  public:
    double GetValue() const { return value; };
    void SetValue(double NewValue) const { value = NewValue; };
};

My exported DLL functions could look like this:

typedef Foo* FOO_HDL;

extern "C" { 

__declspec(dllexport) FOO_HDL __stdcall FooCreate() {
  return new Foo();
};

__declspec(dllexport) void __stdcall FooDestroy(FOO_HDL obj) {
  delete obj;
};

__declspec(dllexport) double __stdcall FooGetValue(FOO_HDL obj) {
  return obj->GetValue();
};

__declspec(dllexport) void __stdcall FooSetValue(FOO_HDL obj, double NewValue) {
  obj->SetValue(NewValue);
};

};

But, to be really safe, you also need to make sure that no exceptions leave the DLL boundary. So, in theory, you would need to wrap all the bodies of all the exported functions with a catch-all clause, as such, for example:

void __stdcall FooSetValue(FOO_HDL obj, double NewValue) {
  try {
    obj->SetValue(NewValue); //if this operation throws an exception, it must not propagate further.
  } catch(...) {             //so, catch all exceptions.
    //do something.. or not.
  };
};

But, the above is a bit tedious and few people do it. If an exception occurs and you don't catch it before the boundary of the DLL is traversed back during stack unwinding, you will get a crash (in some case that's acceptable, in others, it is not).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.