[英]how to call a C++ dll exported function from 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
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;
}
}
我為debug和releas編譯了這個,並將它復制到我的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 / 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#以匹配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.