1

Possible Duplicate:
A call to PInvoke function '[…]' has unbalanced the stack

I'm trying to wrap a few functions written in c++, in order to use them in a c# program (WPF, or as an example a console app), but get run-time exceptions.

I guess this is a compilation issue (of either the c++ project of the C# one). When I change the platform target for the C# projects, I get different exceptions. when the platform target is x64 I get

An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

When I try to compile it as x86, I get:

A call to PInvoke function 'Wrapper!Wrapper.IWrapper::create' 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.

I'm running VS2010 on windows 7 64.

Would be happy for any ideas on how to solve this.

This is what I do:

c++ code. cpp:

int create(int Handle)
{
    return 1;
}

and h:

#define EXPORT_DLL __declspec(dllexport)

extern "C"
{
EXPORT_DLL int create(int Handle);
}

Then in a second C# project, I call this dll, where the c++ project's name is wrapAttemptC

namespace Wrapper
{
    internal class IWrapper
    {
        const string SHADOW_DLL_NAME = "wrapAttemptC.dll";

        [DllImport(SHADOW_DLL_NAME)]
        public static extern int create(int Handle);
    }
    public class CWW
    {
        public CWW(){}

        public int Connect(int cam)
        {
            return IWrapper.create(cam);
        }
    }
}

Then, I put the DLL file created in the c++ project in the bin/Debug of this c# project and of the app c# project (WPF), and try to call

CWW cww = new CWW();
cww.Connect(5);
Community
  • 1
  • 1
Omri374
  • 2,555
  • 3
  • 26
  • 40

1 Answers1

2

The default calling convention for C++ exported functions is cdecl, but the default calling convention for the DllImport attribute is WinApi (which defaults to stdcall). So you have a mismatch there that could indeed mess up your stack. Try stating the calling convention explicitly in the DllImport Attribute, your C++ function declaration, or better, both (so that they match). Like this:

EXPORT_DLL __stdcall int create(int Handle);

And in your C# project:

[DllImport(SHADOW_DLL_NAME, CallingConvention = CallingConvention.StdCall)]
Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • Eventually I used the `cdecl` calling convention in the C# code, so it would fit the c++ functions. I changed `[DLLImport(SHADOW_DLL_NAME)]` to `[DllImport(SHADOW_DLL_NAME, CallingConvention = CallingConvention.Cdecl)]` and that did the trick. Thanks for all the useful answers and comments! – Omri374 May 16 '12 at 06:18