Calling unmanaged DLL from vb.net

I need to consume an unmanaged (WIN32) DLL with my VB.NET application. I have read several articles and gone in circles in the MS documentation about doing this. All my attempts result in a "stack imbalance" exception. The first method I need to access takes a pointer to a structure as a parameter and returns a value from an enumeration:
AVRPODS_API IDBE_ERROR avr_init(AVR_POD_OPTIONS *lpsEepromOptions);

Open in new window

The structure looks like this:
typedef struct tagPodOptions {
	int					iPodType ;
	unsigned char		ucJTAGClockDelay ;
	AVR_EEPROM_CONTROL	eEepromControl ;
	wchar_t				wcsEepromFilename[MAX_PATH] ;
} AVR_POD_OPTIONS ;

Open in new window


My last attempt wit the VB.NET code looks like this:
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure podOptions
        <MarshalAs(UnmanagedType.U4)> Public iPodType As Integer
        <MarshalAs(UnmanagedType.U1)> Public ucClockDelay As Char
        <MarshalAs(UnmanagedType.U4)> Public eEEPROMControl As Integer
        <MarshalAs(UnmanagedType.LPStr)> Public eepromFilename As String
    End Structure
    '
    Public Enum IDBE_ERROR
        eOK         ' just a dummy for now
    End Enum

    <DllImport("avr_pods", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Private Shared Function avr_init(ByRef eepromOptions As podOptions) As IDBE_ERROR
    End Function

Open in new window

Thanks,
Sid.
Sid PriceSoftware Systems Architect/DesignerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

it_saigeDeveloperCommented:
Have you tried:
<StructLayout(LayoutKind.Sequential)> _
Public Structure podOptions
	Public iPodType As UInteger
	Public ucClockDelay As Char
	Public eEEPROMControl As UInteger
	<MarshalAs(UnmanagedType.LPStr)> Public eepromFilename As String
End Structure

Open in new window


Here is a great article on Marshaling:

http://www.codeproject.com/Articles/66245/Marshaling-with-Csharp-Chapter-1-Introducing-Marsh.aspx

-saige-
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Sid PriceSoftware Systems Architect/DesignerAuthor Commented:
Thank you, that is a very comprehensive article however I am having trouble translating it to VB.NET because it would appear that my code should work. The only issues I thought it had were with the return type and the string pointer in the structure so I changed them to:
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure podOptions
        <MarshalAs(UnmanagedType.U4)> Public iPodType As Integer
        <MarshalAs(UnmanagedType.U1)> Public ucClockDelay As Char
        <MarshalAs(UnmanagedType.U4)> Public eEEPROMControl As Integer
        <MarshalAs(UnmanagedType.LPWStr)> Public eepromFilename As String
    End Structure
    '
    <DllImport("avr_pods", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Private Shared Function avr_init(ByRef eepromOptions As podOptions) As Integer
    End Function

Open in new window


I still got the same exception, so I must still be doing something wrong here.
Sid.
0
ArkCommented:
It may depend on platform. For x64 pointer should be IntPtr, not Integer
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Sid PriceSoftware Systems Architect/DesignerAuthor Commented:
Ark, I don't understand what you wrote ... the only pointer is the parameter "eepromOptions", I did not use "Integer" as a pointer. The return value is an enum value.
Sid.
0
Sid PriceSoftware Systems Architect/DesignerAuthor Commented:
I have resolved the problem by adding a "CallingConvention" attribute to the "DllImport" statement:

    
<DllImport("avr_pods", SetLastError:=True, CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.Cdecl)> _
Private Shared Function avr_init(ByRef eepromOptions As podOptions) As Integer
End Function

Open in new window


Sid.
0
Sid PriceSoftware Systems Architect/DesignerAuthor Commented:
This article while not directly applicable to VB.NET did lead me to question my code and ultimately to the answer.
Sid.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.