如何调用C ++ dll导出函数从c# [英] how to call a C++ dll exported function from c#

查看:194
本文介绍了如何调用C ++ dll导出函数从c#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次尝试混合c#非托管C ++,这可能是一个非常简单的问题,但我不能得到它。



我需要从C ++ dll调用一些函数到C#代码。下面是dll项目的代码:



.h文件:

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

externC
{
DECLDIR int Add(int a,int b);
DECLDIR void Function(void);
}

.cpp文件

  #includestdafx.h
#includemyFct.h
#include< iostream>

externC
{
DECLDIR int Add(int a,int b)
{
return(a + b);
}

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



我编译了这个为调试和释放和复制它在我的C#项目的 debug 文件夹中。



以下是c#代码:

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


var cyu = Add(3,5);

当我尝试运行时,我得到


托管调试助手PInvokeStackImbalance检测到C:\Program Files\ Microsoft Office \Office14 \WINWORD.EXE中的问题
其他信息:调用PInvoke函数'MyAddin!MyAddin.ThisAddIn :: Add'具有不平衡的堆栈,这可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

但是我看到的签名是一样的。我缺少什么?



谢谢!

解决方案

DLLImport的调用约定是stdcall,但是你的C ++代码的默认是cdecl。您看到的错误消息是当调用约定不匹配时显示的错误消息。这两个调用约定的参数堆栈清理要求是不同的,P / Invoke marshaller检测并报告这一点。



修复是使调用约定匹配。 / p>

例如,您可以这样更改您的P / Invoke:

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

另一个选项是更改您的C ++:

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

显然,你应该只做其中一个。如果你改变两个C#和C ++,你会有相同的问题反向!



如果我是你,我会把C ++代码作为cdecl,并更改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.

这篇关于如何调用C ++ dll导出函数从c#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆