简体   繁体   中英

how to call a C++ dll exported function from c#

This is the first time I'm trying to mix c# an unmanaged C++ so this might be a very simple question , but I don't get it.

I need to call some functions from a C++ dll into C# code. Here is the code for the dll project:

the .h file :

#pragma once 
#include <iostream>
#if defined FIRSTDLL_EXPORTS
    #define DECLDIR __declspec(dllexport)
#else
    #define DECLDIR __declspec(dllimport)
#endif

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

the .cpp file

#include "stdafx.h"
#include "myFct.h"
#include <iostream>

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

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

I compiled this for both the debug and releas and copied it in the debug folder of my C# project. Neither version worked.

Here is the c# code:

[DllImport("firstDLL.Dll")]
public static extern int Add(int a, int b);


var cyu = Add(3, 5);

And when I try to run this I get

"Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\\Program Files\\Microsoft Office\\Office14\\WINWORD.EXE'. Additional Information: A call to PInvoke function 'MyAddin!MyAddin.ThisAddIn::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."

But as I see the signatures are the same. What am I missing??

Thanks!

The default calling convention for DLLImport is stdcall, but the default of your C++ code is cdecl. The error message you have seen is what is shown when the calling conventions don't match. The parameter stack cleanup requirements are different for these two calling conventions, and the P/Invoke marshaller detects and reports this.

The fix is to make your calling conventions match.

For example you could change your P/Invoke like so:

[DllImport("firstDLL.Dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Add(int a, int b);

The other option is to change your C++:

#if defined FIRSTDLL_EXPORTS(returntype)
    #define DECLDIR __declspec(dllexport) returntype __stdcall
#else
    #define DECLDIR __declspec(dllimport) returntype __stdcall
#endif

Clearly you should only do one of these. If you change both C# and C++ you'll have the same problem in reverse!

If I were you I would leave the C++ code as cdecl and change the C# to match.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM