如何调用C ++的DLL导出从C#功能 [英] how to call a C++ dll exported function from c#

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

问题描述

这是我第一次尝试将C#的托管C ++所以这可能是一个很简单的问题,但我不明白这一点。

我需要调用从C ++ DLL的一些功能到C#code。这里是$ C $下的dll项目:

.h文件:

 的#pragma一次
#包括<的iostream>
#如果定义FIRSTDLL_EXPORTS
    #定义DECLDIR __declspec(dllexport)的
#其他
    #定义DECLDIR __declspec(dllimport的)
#ENDIF

为externC
    {
      DECLDIR INT添加(INT A,INT B);
      DECLDIR void函数(无效);
    }
 

.cpp文件

 的#includestdafx.h中
#包括myFct.h
#包括<的iostream>

为externC
{
      DECLDIR INT添加(INT A,INT B)
      {
          返回(A + B);
}

      DECLDIR void函数(无效)
      {
          性病::法院<< DLL叫! <<的std :: ENDL;
      }
}
 

我编这两个调试和releas和调试我的C#项目文件夹复制它。无论是版的工作。

下面是C#code:

  [的DllImport(firstDLL.Dll)
公共静态外部INT添加(INT A,INT B);


VAR CYU =添加(3,5);
 

当我尝试运行此我得到

托管调试助手PInvokeStackImbalance检测到一个问题,C:\ Program Files文件\微软的Office \ OFFICE14 \ WINWORD.EXE。 其他信息:调用PInvoke的函数MyAddin MyAddin.ThisAddIn ::加入!'已不平衡的堆栈。这可能是因为管理的PInvoke签名也非托管的目标签名不匹配。检查调用约定和的PInvoke签名的参数匹配目标非托管签名。

但是,当我看到签名是相同的。我在想什么?

谢谢!

解决方案

默认调用约定的DllImport是STDCALL,但你的C ++ code,其默认为的cdecl。你所看到的错误消息是显示当调用约定不匹配。参数堆栈的清理要求这两个调用约定不同的,和P / Invoke的编组检测并报告此。

解决方法是让你的调用约定相匹配。

例如,你可以改变你的P / Invoke,像这样:

  [的DllImport(firstDLL.Dll,CallingConvention = CallingConvention.Cdecl)
公共静态外部INT添加(INT A,INT B);
 

另一种选择是改变你的C ++:

 #如果定义FIRSTDLL_EXPORTS(返回类型)
    #定义DECLDIR __declspec(dllexport)的返回类型__stdcall
#其他
    #定义DECLDIR __declspec(dllimport的)的返回类型__stdcall
#ENDIF
 

显然,你应该只做其中之一。如果要更改C#和C ++你就会有完全相反的问题!

如果我是你,我会离开的C ++ code为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天全站免登陆