我编写了自己的函数,使用标准Win32调用约定在C中声明这样的函数:
int Thing( char * command, char * buffer, int * BufSize);
我有以下数量的Visual Basic代码,它应该导入DLL文件并调用此函数,将其包装起来以便于调用Thing(“CommandHere”,GetDataBackHere)。
更新:此代码现在是一个有效的解决方案,如下所示:
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Imports System
Imports System.Text
Namespace dllInvocationSpace
Public Class dllInvoker
' I tried attributes, but I could not make it build:
' <DllImport("thing1.dll", False, CallingConvention.Cdecl, CharSet.Ansi, "Thing", True, True, False, True)>
Declare Ansi Function Thing Lib "thing1.dll" (ByVal Command As String, ByRef Buffer As StringBuilder, ByRef BufferLength As Integer) As Integer
' This part contributed by helpful user:
Shared Function dllCall(ByVal Command As String, ByRef Results As String) As Integer
Dim Buffer As StringBuilder = New StringBuilder(65536)
Dim Length As Integer = Buffer.Capacity
Dim retCode As Integer = Thing(Command, Buffer, Length)
Results = Buffer.ToString()
'Debug.Assert(Results.Length = Length) ' This assertion is not true for me
Return retCode
End Function
End Class
End Namespace
我按照这里收到的帮助获得了构建代码,然后我忘记了As Return Type
(它让我得到了MarshalDirectiveException PInvokeRestriction)。然后我在我的DLL中有一个断言失败,导致SEHException。一旦修复,这将非常有效。谢谢大家。有些新闻组人们都说不能这样做,Visual Basic只加载托管的DLL程序集(我猜这是大多数Visual Basic用户习惯的正常事情)。
答案 0 :(得分:2)
这取决于您在C代码中如何使用缓冲区参数。如果你只是将从你的VB.NET代码传递给你的C代码,那么声明它的ByVal String就足够了。但是,如果您让C代码在缓冲区中返回一个字符串,那么您必须将它声明为ByVal StringBuilder并在调用之前正确初始化它。例如:
Public Class dllInvoker
Declare Ansi Function Thing Lib "Thing1.dll" (ByVal Command As String, ByVal Buffer As StringBuilder, ByRef BufferLength As Integer) As Integer
Shared Function dllCall(ByVal Command As String, ByRef Results As String) As Integer
Dim Buffer As StringBuilder = New StringBuilder(65536)
Dim Length As Integer = Buffer.Capacity
Dim retCode As Integer = Thing(Command, Buffer, Length)
Results = Buffer.ToString()
Debug.Assert(Results.Length = Length)
Return retCode
End Function
End Class
请注意返回的Length值中的歧义。
答案 1 :(得分:0)
您无法将StringBuilder
实例转换为string
实例,而是使用'ToString'方法将其转换回string
类型...这里是dllCall
函数中的代码...
retCode = Thing(Command, Buffer, bufsz) Results = Buffer.ToString();