简体   繁体   English

如何从c#调用C ++ DLL导出函数

[英]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. 这是我第一次尝试将c#与非托管C ++混合使用,所以这可能是一个非常简单的问题,但我不明白。

I need to call some functions from a C++ dll into C# code. 我需要从C ++ DLL调用一些函数到C#代码。 Here is the code for the dll project: 这是dll项目的代码:

the .h file : .h文件:

#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 .cpp文件

#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. 我为debug和releas编译了这个,并将它复制到我的C#项目的debug文件夹中。 Neither version worked. 这两个版本都没有用。

Here is the c# code: 这是c#代码:

[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." “托管调试助手'PInvokeStackImbalance'在'C:\\ Program Files \\ Microsoft Office \\ Office14 \\ WINWORD.EXE'中检测到问题。附加信息:对PInvoke函数'MyAddin!MyAddin.ThisAddIn :: Add'的调用已失去平衡这很可能是因为托管的PInvoke签名与非托管目标签名不匹配。请检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。“

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. DLLImport的默认调用约定是stdcall,但是C ++代码的默认值是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. 对于这两个调用约定,参数堆栈清理要求是不同的,并且P / Invoke marshaller检测并报告它。

The fix is to make your calling conventions match. 修复方法是使您的调用约定匹配。

For example you could change your P/Invoke like so: 例如,您可以像这样更改P / Invoke:

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

The other option is to change your C++: 另一种选择是改变你的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! 如果你同时改变C#和C ++,那么反过来也会遇到同样的问题!

If I were you I would leave the C++ code as cdecl and change the C# to match. 如果我是你,我会将C ++代码保留为cdecl并更改C#以匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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