Link to home
Start Free TrialLog in
Avatar of mileyja
mileyja

asked on

Convert c# code to vb.net

I asked a question at the following URL that has more specific information.  

https://www.experts-exchange.com/questions/22976921/dllimport-help-from-c-c-unmanaged-dll-to-managed-wrapper.html

In short, it wraps a function from an unmanaged c++ dll and gives me access in C#.  I can currently build the c# project as a dll and reference it in a vb.net project but I would rather be able to have the new wrapped api itself in vb.net since I know a lot more about it and can make changes later.

This one is worth 500 points if you can convert this to vb.net 2005 code in a context that works for  my problem.
[StructLayout(LayoutKind.Sequential)]
private struct APCDeviceDescription {
    public IntPtr next;
    public IntPtr name;
    public IntPtr description;
}
 
public class APCDevice {
    public string name;
    public string description;
}
 
[DllImport("airpcap.dll")]
private extern static unsafe int AirpcapGetDeviceList(APCDeviceDescription** ppDevices, char* pBuf);
 
[DllImport("airpcap.dll")]
private extern static unsafe int AirpcapFreeDeviceList(APCDeviceDescription* pDevices);
 
public static unsafe int AirpcapGetDeviceListWrap(out APCDevice[] outDevices, ref string outErrors) {
    List<APCDevice> devicesToRet = new List<APCDevice>();
    APCDeviceDescription* pDevices = (APCDeviceDescription*)0;
    APCDeviceDescription** ppDevices = &pDevices;
    char*pErrorBuffer = stackalloc char[513];
    int result = 0;
    try {
        result = AirpcapGetDeviceList(ppDevices, pErrorBuffer);
    } finally {
        if (result != 0) {
            APCDeviceDescription* pDevice = pDevices;
            while (pDevice != (APCDeviceDescription*)0) {
                APCDevice newDev = new APCDevice();
                newDev.name = Marshal.PtrToStringAnsi(pDevice->name);
                newDev.description = Marshal.PtrToStringAnsi(pDevice->description);
                devicesToRet.Add(newDev);
                pDevice = (APCDeviceDescription*)pDevice->next;
            }
            AirpcapFreeDeviceList(pDevices);
            //
            outDevices = devicesToRet.ToArray();
            outErrors = null;
        } else {
            List<char> listChars = new List<char>();
            char charFromBuf = pErrorBuffer[0];
            while (charFromBuf != 0) {
                listChars.Add(charFromBuf);
            }
            char[] errorsCharArray = listChars.ToArray();
            //
            outErrors = new String(errorsCharArray);
            outDevices = null;
        }
    }
    return ( result );
}

Open in new window

Avatar of Wayne Taylor (webtubbs)
Wayne Taylor (webtubbs)
Flag of Australia image

How's this?
<StructLayout(LayoutKind.Sequential)> _
Private Structure APCDeviceDescription
    Public [next] As IntPtr
    Public name As IntPtr
    Public description As IntPtr
End Structure
Public Class APCDevice
    
    Public name As String
    Public description As String
End Class 
<DllImport("airpcap.dll")> _
Private Shared Function AirpcapGetDeviceList(ByVal ppDevices As APCDeviceDescription**, ByVal pBuf As Char*) As Integer
End Function 
<DllImport("airpcap.dll")> _
Private Shared Function AirpcapFreeDeviceList(ByVal pDevices As APCDeviceDescription*) As Integer
End Function 
Public Shared Function AirpcapGetDeviceListWrap(ByRef outDevices As APCDevice(), ByRef outErrors As String) As Integer
    Dim devicesToRet As New List(Of APCDevice)()
    Dim pDevices As APCDeviceDescription* = DirectCast(0, APCDeviceDescription*)
    Dim ppDevices As APCDeviceDescription** = AddressOf
    Dim pErrorBuffer As Char* = 
    Dim result As Integer = 0
    Try
        result = AirpcapGetDeviceList(ppDevices, pErrorBuffer)
    Finally
        If result <> 0 Then
            Dim pDevice As APCDeviceDescription* = pDevices
            While pDevice <> DirectCast(0, APCDeviceDescription*)
                Dim newDev As New APCDevice()
                newDev.name = Marshal.PtrToStringAnsi()
                newDev.description = Marshal.PtrToStringAnsi()
                devicesToRet.Add(newDev)
                pDevice = DirectCast(, APCDeviceDescription*)
            End While
            AirpcapFreeDeviceList(pDevices)
            '
            outDevices = devicesToRet.ToArray()
            outErrors = Nothing
        Else
            Dim listChars As New List(Of Char)()
            Dim charFromBuf As Char = pErrorBuffer(0)
            While charFromBuf <> 0
                listChars.Add(charFromBuf)
            End While
            Dim errorsCharArray As Char() = listChars.ToArray()
            '
            outErrors = New String(errorsCharArray)
            outDevices = Nothing
        End If
    End Try
    Return (result)
End Function

Open in new window

Avatar of mileyja
mileyja

ASKER

  <DllImport("airpcap.dll")> _
Private Shared Function AirpcapGetDeviceList(ByVal ppDevices As APCDeviceDescription**, ByVal pBuf As Char*) As Integer
    End Function

<DllImport("airpcap.dll")> _
Private Shared Function AirpcapFreeDeviceList(ByVal pDevices As APCDeviceDescription*) As Integer
    End Function

I tihnk your close it doesnt like those asterisks that are used in the c#, I don't even know what those stupid things mean, any thoughts??  
I don't know VB, there some explanations using C#:
APCDeviceDescription val; <-- this is value type object variable declaration;
APCDeviceDescription * pVal; <-- this is declaration of pointer (it points to value with type APCDeviceDescription). Pointer points to your in-process memory.

fixed(pVal = &val) {// do something with pointer}; <-- taking address of variable val and putting it to pointer pVal
(i think in VB '&' operator == 'AddressOf' operator)

Why 'fixed'? Fixed statement means that garbage collection should not move 'val' in memory, so your pointer will always point to real 'val'.

APCDeviceDescription * * pVal; <-- this is declaration of pointer to pointer =). Using pointer to pointer your AirpcapGetDeviceList can put address of pointer (APCDeviceDescription*) to your variable (pointer to pointer variable). =)
Avatar of mileyja

ASKER

so what do the asterisks actually mean??
ASKER CERTIFIED SOLUTION
Avatar of wizrr
wizrr
Flag of Russian Federation image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mileyja

ASKER

please tell me where Im wrong now that your on in this other questions

https://www.experts-exchange.com/questions/22981334/dllimport-help-from-c-c-unmanaged-dll-to-managed-c-wrapper.html

I think maybe there is a problem with the struct conversion, the intptr it returns seems like it comes back with a valid reference but something is just not quite there and im sure you can tell me what it is.

if there isn't much of a performance hit ill just not bother converting to vb.net and just reference the c# project in vb.net

The fact you don't think the unsafe code can be converted really makes the other question mega priority!!