如何调用 C++ C# 的 dll 导出函数
这是我第一次尝试将 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
extern "C"
{
DECLDIR int Add( int a, int b );
DECLDIR void Function( void );
}
.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;
}
}
我为调试和发布编译了此文件,并将其复制到我的 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 签名的调用约定和参数是否与目标非托管签名匹配。”
但正如我所见,签名是相同的。我缺少什么?
谢谢!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
DLLImport 的默认调用约定是 stdcall,但 C++ 代码的默认调用约定是 cdecl。您看到的错误消息是调用约定不匹配时显示的内容。这两种调用约定的参数堆栈清理要求不同,P/Invoke 编组器会检测并报告这一点。
解决方法是使您的调用约定匹配。
例如,您可以像这样更改您的 P/Invoke:
另一种选择是更改您的 C++:
显然您应该只执行其中之一。如果你同时更改 C# 和 C++,你将会遇到同样的问题!
如果我是你,我会将 C++ 代码保留为 cdecl 并更改 C# 以匹配。
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:
The other option is to change your C++:
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.