Import a C++ DLL into C#

Viewed 504

I try to implement a C++ DLL into my C# project. I've given the following header file:

#ifdef EBEXPORT
const long EBDECL
#else
const long EBDECL __declspec(dllimport)
#endif

const long EBCALL __stdcall


#if defined (__cplusplus)
extern "C" 
{
#endif

EBDECL long EBCALL EbInitTcp(long nUnit, const char* pIP, long nIPSize);

#if defined (__cplusplus)
}
#endif

This is my code which I use to implement the DLL in C#:

using System.Runtime.InteropServices;

namespace NoName
{
    class DLLImport
    {
        [DllImport("C:/lib/host.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern long EbInitTcp(long nUnit, string pIP, long nIPSize);

        public void Init()
        {
            string ip = "192.168.0.1";
            EbInitTcp(1, ip, ip.Length));
        }

    }
}

If I execute the code I get a PInvokeStackImbalance exception. Could you please help me?

2 Answers

Verify your calling convention; beware that extern "C" defaults to CallingConvention.Cdecl. This error is usually caused by wrong calling convention.

Also beware that C#'s long and C++'s long may be different.

It looks like you're trying to specify __stdcall, but it's a syntax error. In any case make sure your calling conventions are synchronized.

The imbalance can be caused by a mismatch calling convention (cdecl vs. stdcall) or mismatch function arguments, both in size and type.

The C++ calling convention definition is little unusual, it is normally defined with a #define.

#ifdef EBEXPORT
  #define EBDECL __declspec(dllexport)
#else
  #define EBDECL __declspec(dllimport)
#endif

#define EBCALL __stdcall

#if defined (__cplusplus)
extern "C" 
{
#endif

EBDECL const long EBCALL EbInitTcp(long nUnit, const char* pIP, long nIPSize);

#if defined (__cplusplus)
}
#endif

On the C# side;

using System.Runtime.InteropServices;

namespace NoName
{
    class DLLImport
    {
        [DllImport("C:/lib/host.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern long EbInitTcp(int nUnit, string pIP, int nIPSize);

        public void Init()
        {
            string ip = "192.168.0.1";
            EbInitTcp(1, ip, ip.Length));
        }

    }
}
Related