内存损坏从vb.net调用c dll

Memory corruption calling C++ dll from VB.NET

本文关键字:调用 dll net vb 损坏 内存      更新时间:2023-10-16

我正在尝试从vb.net中调用c dll的函数,但是正在遇到以下错误:

托管调试助手'pinvokestackimbalance'在" d:... allow_project_in_vb.vshost.exe'。

附加信息:调用pinvoke函数'tall_project_in_vb! calle_project_in_vb.module1 :: add'堆栈不平衡。这可能是因为托管PinVoke签名与非托管目标签名不符。检查PINVOKE签名的调用惯例和参数是否与目标不受管理的签名相匹配。

我希望有人能在这个东西中精通这个东西,以发现我出错的地方吗?我将不胜感激任何建议,到目前为止,Googles在帮助我确定问题是什么方面没有生产力。这是我试图运行的小示例:

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

dllimportattribte的默认调用惯例被列为:

呼叫范围字段的默认值是Winapi,进而默认为stdcall judvention。

但是,C 程序的默认值为__cdecl

您的C 代码似乎通过未指定替代方案使用此默认值,因此VB签名应为:

<DllImport("D:...called_c.dll", EntryPoint:="add", ExactSpelling:=False, CallingConvention:=CallingConvention.Cdecl)>
Public Function add(ByRef a As Int32, ByRef b As Int32) As Int32
End Function

另外,您可能需要将Inatibute添加到参数中,以防止Interop Marshaler的任何值复制。

<DllImport("D:...called_c.dll", EntryPoint:="add", ExactSpelling:=False, CallingConvention:=CallingConvention.Cdecl)>
Public Function add(<[In]()> ByRef a As Int32, <[In]()> ByRef b As Int32) As Int32
End Function

几乎所有的C 指针等于.NET世界中的 IntPtr ,因此您的参数应为该类型。但是,正如Crashmstr所说,如果您只将两个数字添加在一起,为什么还要首先需要它们成为指示?

<DllImport("D:...called_c.dll", EntryPoint:="add", ExactSpelling:=False)>
Public Function add(ByVal a As IntPtr, ByVal b As IntPtr) As Integer
End Function

还要注意,该参数应作为ByVal传递,因为当前C 函数不包括预期通过参考传递的参数。

用法示例:

Dim Result As Integer = add(New IntPtr(3), New IntPtr(6))
MessageBox.Show(Result) 'Should display "9".