c - 从 VB.net 调用 DLL 导致堆异常
问题描述
我用 gcc 制作了一个 DLL,它只包含以下函数:
#include <windows.h>
BSTR __declspec(dllexport) testfunc(void)
{
return SysAllocString(L"Hello");
}
这是基于此答案末尾的代码。构建命令是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
按照我链接的线程上的建议通过参数“返回”字符串,但这在客户端似乎需要做很多工作,我想让它尽可能简单对于客户,即看看我是否能让这种方法发挥作用。
解决方案
为了在托管代码和非托管代码之间传递数据,必须对其进行适当的编组。由于运行时无法知道您的testfunc()
返回值,您必须通过提供它的声明来告诉它,您通过
<DllImport("testfunc.dll")>
Private Function testfunc() As String
但是返回类型是 a 的信息String
是模棱两可的,因为有多种字符串表示方式。使用MarshalAs -Attribute 告诉运行时如何处理返回值:
<DllImport("testfunc.dll")>
Private Function testfunc() As <MarshalAs(UnmanagedType.BStr)> String
阅读有关托管和非托管代码之间的互操作封送处理和传递字符串的更多信息。
推荐阅读
- vba - 将注释插入另一个单元格 Excel 中的最后一个单元格
- javascript - 如何在其他函数之前调用异步函数
- amazon-web-services - 在 AWS 中运行 Spring Boot 应用程序无法启动
- android - JSON 反序列化 - Firebase 到 Android 应用程序
- java - 使用 Pivot 作为数组中最后一个元素的快速排序分析
- javascript - 如何获得不同类型的通知?
- twitter - twitter 源到使用水槽的蜂巢水槽
- flask - What does this code in .cicleci/config.yml mean?
- rxjs - forkEpic,redux-observable 1.0.0-alpha.2,打字稿
- python - Tkinter:实时从子进程输出更新 GUI