kevp
kevp

Reputation: 377

This simple C++ DLL is not working in C#

I have been spending the day working on come c++ code that I need to run in c#. I ran through this DLL tutorial and have been having trouble using it in my c# app. I will post all the code below.

I am getting this PInvokeStackImbalance error: 'A call to PInvoke function 'frmVideo::Add' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.'

Thanks as always, Kevin

DLLTutorial.h

#ifndef _DLL_TUTORIAL_H_
#define _DLL_TUTORIAL_H_
#include <iostream>

#if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif

extern "C"
{
   DECLDIR int Add( int a, int b );
   DECLDIR void Function( void );
}

#endif

DLLTutorial.cpp

#include <iostream>

#define DLL_EXPORT

#include "DLLTutorial.h"


extern "C"
{
   DECLDIR int Add( int a, int b )
   {
      return( a + b );
   }

   DECLDIR void Function( void )
   {
      std::cout << "DLL Called!" << std::endl;
   }
}

C# code to use the DLL:

using System.Runtime.InteropServices;
[DllImport(@"C:\Users\kpenner\Desktop\DllTutorialProj.dll"]
public static extern int Add(int x, int y);
int x = 5;
int y = 10;
int z = Add(x, y);

Upvotes: 0

Views: 908

Answers (1)

David Heffernan
David Heffernan

Reputation: 612804

You C++ code uses the cdecl calling convention and the C# code defaults to stdcall. This mismatch explains the message that you see.

Make the two sides of the interface match:

[DllImport(@"...", CallingConvention=CallingConvention.Cdecl]
public static extern int Add(int x, int y);

Alternatively you could use stdcall for your C++ exports:

DECLDIR __stdcall int Add( int a, int b );

It's up to you which of these two options you choose, but make sure that you only change one side of the interface and not both, for obvious reasons!

Upvotes: 5

Related Questions