【发布时间】:2017-03-08 20:41:42
【问题描述】:
我正在尝试从 vb.net 调用 C++ dll 中的函数,但遇到以下错误:
托管调试助手“PInvokeStackImbalance”在“D:...\calling_project_in_VB.vshost.exe”中检测到问题。
附加信息:调用 PInvoke 函数 'calling_project_in_VB! call_project_in_VB.Module1::add' 使堆栈不平衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。
我希望有人可能对这些东西足够精通以发现我哪里出错了?我将不胜感激任何建议,到目前为止,谷歌在帮助我确定问题所在方面一直没有成效。这是我正在尝试运行的可重现的小示例:
C++ 是这样设置的:
调用_c.h:
extern "C" __declspec( dllexport )
int add(int* a, int* b);
调用_c.cpp:
#include "stdafx.h"
#include "called_c.h"
#include <string>
using namespace std;
// using namespace System;
int add(int* a, int* b)
{
int Aa = *a;
int Bb = *b;
return Aa + Bb;
}
这是尝试调用 C 的 VB 函数(其中“...”是我机器上的路径):
Imports System.Runtime.InteropServices
Imports System
Module Module1
'Public Class called_c
<DllImport("D:\...\called_c.dll", EntryPoint:="add", ExactSpelling:=False)>
Public Function add(ByRef a As Int32, ByRef b As Int32) As Int32
End Function
'End Class
Sub Main()
Dim val1 As Int32
Dim val2 As Int32
Dim answer As Int32
val1 = 3
val2 = 4
answer = add(val1, val2)
MsgBox(answer)
End Sub
End Module
【问题讨论】:
-
你到底为什么要传递 int 指针来添加它们(你不需要无论如何都需要这些引用)。
-
@crashmstr 这只是一个可重复的小例子,我希望能作为一个更复杂问题的前兆,其中 0 填充的向量将被传递到 c 代码中,填充,然后返回到VB。如果你有一个小的工作示例,如果你能分享它,我将非常感激。
-
我不知道这是否会有所帮助,但您可以尝试将
<[In]()>attribute 添加到ByRef参数中,以防止 Marshaler 将值复制回来。 -
@TnTinMn
CallingConvention:=CallingConvention.Cdecl工作!在应用于“现实世界”问题之前,继续对我的小示例进行下一次修改。 -
你应该将他的答案标记为接受。 :)