代码之家  ›  专栏  ›  技术社区  ›  M.M

从VB.net调用DLL会导致堆异常

  •  2
  • M.M  · 技术社区  · 7 年前

    我用gcc创建了一个仅包含以下函数的DLL:

    #include <windows.h>
    
    BSTR __declspec(dllexport) testfunc(void)
    {
         return SysAllocString(L"Hello");
    }
    

    this answer . 生成命令无效 gcc -shared -o testfunc.dll main.c -Os -s -loleaut32 .

    在使用VS 2017社区的Visual Basic中,我的代码是:

    Imports System.Runtime.InteropServices
    Imports Microsoft.VisualBasic
    Imports System
    Imports System.Text
    
    Module Module1
        <DllImport("testfunc.dll", CallingConvention:=CallingConvention.Cdecl
                   )>
        Private Function testfunc() As String
        End Function
    
        Sub Main()
        Dim Ret = testfunc()
        Console.WriteLine(Ret)
        End Sub
    End Module
    

    但是,执行程序会在从返回时导致异常 testfunc . 执行永远达不到目标 Console.WriteLine

    The program '[15188] ConsoleApp1.exe' has exited with code -1073740940 (0xc0000374).
    

    表示堆损坏。我做错什么了?


    我试过但没用的东西:

    • 正在更改为 __stdcall Declare Auto Function testfunc Lib "testfunc.dll" Alias "testfunc@0" () As String 而不是 <DllImport...>

    • 改变函数返回整数;但是我当然不能访问我的字符串。

    ByRef StringBuilder 在我链接的线程上建议的参数,但是在客户端似乎有很多工作要做,我想让它对客户端尽可能简单,也就是说,看看我是否可以让这种方法工作。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Visual Vincent    7 年前

    testfunc() 返回时,你必须提供一个声明来告诉它,你是这样做的

    <DllImport("testfunc.dll")>
    Private Function testfunc() As String
    

    但是返回类型是 String 是不明确的,因为有许多方式的字符串表示。使用 MarshalAs -属性来告诉运行时如何处理返回值:

    <DllImport("testfunc.dll")>
    Private Function testfunc() As <MarshalAs(UnmanagedType.BStr)> String
    

    Interop Marshaling Passing strings between managed and unmanaged code .