Question How to use a function from an unmanaged DLL

Snowflake

Member
Joined
Sep 16, 2014
Messages
15
Programming Experience
Beginner
Can anyone please tell me how to declare this unmanaged function in my VB.NET project, I have been at it for hours and I am getting nowhere:confused:.
The integer's and even the struct I can probably manage, but I am having real problems with pointers and the callback.

The function in the external DLL
VB.NET:
int __stdcall SolveEx(
  unsigned int uiWidth,
  unsigned int uiHeight,
  char* pcBoard,
  char* pcSolution,
  unsigned int uiSolutionBufferSize,
  PluginStatus * psStatus,
  PLUGINCALLBACK * pc
);

struct PluginStatus {
  unsigned int uiSize,
  unsigned int uiFlags,
  __int64 i64MovesGenerated,
  __int64 i64PushesGenerated,
  __int64 i64StatesGenerated,
  char szStatusText[256],
  unsigned int uiPluginTimeMS
};

int __stdcall PluginCallback(
  void
);

Thanks
 
I understand the basics, but it is not something which I have dealt with recently, hence the question.


In the rare instances when I have used unmanaged code it has mostly been for using unmanaged Win32 APIs.

Thanks for replying.
 
Last edited:
Am I way off with:
    <DllImport("YASS.dll", EntryPoint:="SolveEx",  CharSet:=CharSet.Unicode, ExactSpelling:=True,  CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function SolveEx(ByVal uiWidth As UInteger, ByVal  uiHeight As UInteger, ByVal pcBoard() As Char, ByRef pcSolution() As  Char _
    , ByVal uiSolutionBufferSize As UInteger, psStatus As PluginStatus) As Integer
    End Function

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> Public Structure PluginStatus
        Public uiSize As UInteger
        Public uiFlags As UInteger
        Public i64MovesGenerated As Int64
        Public i64PushesGenerated As Int64
        Public i64StatesGenerated As Int64
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> Public szStatusText As String
        Public uiPluginTimeMS As UInteger
    End Structure
 
I'm no expert when it comes to PInvoke myself, so I'd probably need a bit of trial and error to get it just right. In principle, your structure looks OK.

With regards to your method, I notice that you have two Char arrays there, but you have declared on ByVal and one ByRef with no justification for the difference. If I'm not mistaken, char pointers are often represented by StringBuilders declared ByVal.

With regards to the callback, you will need to declare a delegate and then declare your method's last parameter as that type, e.g.
Public Delegate Function PluginCallback() As Integer
 
Please can you have a look at this and tell me what major thing I have got wrong, PCallback is called twice and then my program unexpectedly closes.


VB.NET:
Const sBoard As String = "####@##$##.####" & Chr(0)
    Public Pstatus As PluginStatus
    Public sbBoard As New StringBuilder(sBoard, sBoard.Length)
    Public sbSolution As New StringBuilder(1024)
    Public Delegate Function PluginCallback() As Integer
    Public Dcalr As PluginCallback = New PluginCallback(AddressOf PCallback)

    Private Sub BtnTest_Click(sender As Object, e As EventArgs) Handles BtnTest.Click
        Dim Rs As Integer = SolveEx(5, 3, sbBoard, sbSolution, 1024, Pstatus, Dcalr)
        MsgBox(Rs)
    End Sub

    Public Function PCallback() As Integer
        MsgBox( Pstatus.uiPluginTimeMS)
        Return 0
    End Function

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> Public Structure PluginStatus
        Public uiSize As UInteger
        Public uiFlags As UInteger
        Public i64MovesGenerated As Int64
        Public i64PushesGenerated As Int64
        Public i64StatesGenerated As Int64
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> Public szStatusText As String
        Public uiPluginTimeMS As UInteger
    End Structure

    <DllImport("YASS.dll", EntryPoint:="SolveEx", CharSet:=CharSet.Auto, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function SolveEx(<MarshalAs(UnmanagedType.U4)> ByVal uiWidth As UInteger, _
    <MarshalAs(UnmanagedType.U4)> ByVal uiHeight As UInteger, _
    <MarshalAs(UnmanagedType.LPStr)> ByVal pcBoard As StringBuilder, _
    <MarshalAs(UnmanagedType.LPTStr)> ByRef pcSolution As StringBuilder, _
    <MarshalAs(UnmanagedType.U4)> ByVal uiSolutionBufferSize As UInteger, _
    <MarshalAs(UnmanagedType.Struct)> ByRef psStatus As PluginStatus, _
    <MarshalAs(UnmanagedType.FunctionPtr)> ByVal PLUGINCALLBACK As PluginCallback) _
    As Integer
    End Function
 
Back
Top