|
-
May 9th, 2012, 07:27 AM
#1
Thread Starter
Addicted Member
Conversion from VC++ to VB.NET
Hi,
Can anybody please help me to convert this code (Structure and its members) which is in VC++ to VB.NET.
Code:
#define GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH 16
#define GBIF_STRING_DATATYPE unsigned char
typedef struct
{
GBIF_STRING_DATATYPE ucMacAddress[GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH]; // unsigned since the adress components can be higher than 128
GBIF_STRING_DATATYPE ucIP[GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH];
GBIF_STRING_DATATYPE ucSubnetMask[GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH];
GBIF_STRING_DATATYPE ucGateway[GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH];
GBIF_STRING_DATATYPE ucAdapterIP[GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH];
GBIF_STRING_DATATYPE ucAdapterMask[GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH];
DWORD dwIPCurrentBootOptions;
CHAR cManufacturerName[32]; // PerkinElmer
CHAR cModelName[32]; // GBIF
CHAR cGBIFFirmwareVersion[32];
CHAR cDeviceName[16];
} GBIF_DEVICE_PARAM;
Regards,
Susheelss
-
May 9th, 2012, 07:43 AM
#2
Re: Conversion from VC++ to VB.NET
Is this for the purpose of calling an unmanaged function?
-
May 9th, 2012, 08:09 AM
#3
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Thanks Mr.jmcilhinney for ur reply.
YES.
I want to send a pointer to this structure as a parameter to a DLL call so that the call returns the values of this structure filled.
-
May 9th, 2012, 11:04 PM
#4
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
I'm not getting how to define the "GBIF_STRING_DATATYPE" as an unsigned char array. Should I have it as Character array or as a String Builder.
-
May 10th, 2012, 07:35 AM
#5
Re: Conversion from VC++ to VB.NET
Try this:-
vbnet Code:
' Public Const GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH = 16 Public Structure GBIF_DEVICE_PARAM <MarshalAs(UnmanagedType.LPStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _ Public ucMacAddress As String <MarshalAs(UnmanagedType.LPStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _ Public ucIP As String <MarshalAs(UnmanagedType.LPStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _ Public ucSubnetMask As String <MarshalAs(UnmanagedType.LPStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _ Public ucGateway As String <MarshalAs(UnmanagedType.LPStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _ Public ucAdapterIP As String <MarshalAs(UnmanagedType.LPStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _ Public ucAdapterMask As String Public dwIPCurrentBootOptions As Integer <MarshalAs(UnmanagedType.LPStr, sizeconst:=32)> _ Public cManufacturerName As String <MarshalAs(UnmanagedType.LPStr, sizeconst:=32)> _ Public cModelName As String <MarshalAs(UnmanagedType.LPStr, sizeconst:=32)> _ Public cGBIFFirmwareVersion As String <MarshalAs(UnmanagedType.LPStr, sizeconst:=16)> _ Public cDeviceName As String End Structure
-
May 10th, 2012, 11:40 AM
#6
Re: Conversion from VC++ to VB.NET
courtesy of c++ to vb
vb Code:
#Const GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH = True
'C++ TO VB CONVERTER NOTE: The following #define macro was replaced in-line:
'ORIGINAL LINE: #define GBIF_STRING_DATATYPE unsigned char
#Const GBIF_STRING_DATATYPE = True
Public Class GB
Public ucMacAddress(DefineConstants.GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH - 1) As Byte ' unsigned since the adress components can be higher than 128
Public ucIP(DefineConstants.GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH - 1) As Byte
Public ucSubnetMask(DefineConstants.GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH - 1) As Byte
Public ucGateway(DefineConstants.GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH - 1) As Byte
Public ucAdapterIP(DefineConstants.GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH - 1) As Byte
Public ucAdapterMask(DefineConstants.GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH - 1) As Byte
Public dwIPCurrentBootOptions As UInteger
Public cManufacturerName As New String(New Char(31){}) ' PerkinElmer
Public cModelName As New String(New Char(31){}) ' GBIF
Public cGBIFFirmwareVersion As New String(New Char(31){})
Public cDeviceName As New String(New Char(15){})
End Class
Friend NotInheritable Class DefineConstants
Public Const GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH As Integer = 16
End Class
-
May 10th, 2012, 11:59 AM
#7
Re: Conversion from VC++ to VB.NET
That would work too. However this:-
c++ Code:
#define GBIF_STRING_DATATYPE unsigned char
Would imply that those members are meant to be treated as strings and not binary data.
-
May 10th, 2012, 11:33 PM
#8
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Thanks Mr.ident and Mr.Niya for your valuable reply.
Mr.Niya now I tried sending the Pointer to this structure(which you posted) in a DLL function call as given below:
HTML Code:
Dim SensorNumDetected As Integer = 1
Dim pGbIF_DEVICE_PARAM As GBIF_DEVICE_PARAM
Dim myptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pGbIF_DEVICE_PARAM))
Marshal.StructureToPtr(pGbIF_DEVICE_PARAM, myptr, False)
DllCallReturnValue = Acquisition_GbIF_GetDeviceList(Marshal.PtrToStructure(myptr, pGbIF_DEVICE_PARAM.GetType()), SensorNumDetected)
The function call signature is as given below:
Code:
<DllImport("Detector.dll")> Public Function Acquisition_GbIF_GetDeviceList(ByRef p_GBIF_DEVICE_PARAM As GBIF_DEVICE_PARAM, ByVal nDeviceCnt As Integer) As Integer
End Function
Now when i call this DLL function the function should fill the structure members values and return zero if success.But instead it is showing error which says :
"The runtime has encountered a fatal error. The address of the error was at 0x6dd8aa31, on thread 0xf34. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack."
Can you please tell what is the change I should be doing.
Regards,
Susheelss.
-
May 11th, 2012, 01:01 AM
#9
Re: Conversion from VC++ to VB.NET
It seems that function is meant to fill out an array of that structure so you should try declaring that API to take an array of the GBIF_DEVICE_PARAM type.
-
May 11th, 2012, 02:07 AM
#10
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
The C++ DLL function is given like this:
Code:
'Function Signature
Acquisition_GbIF_GetDeviceList(GBIF_DEVICE_PARAM* pGBIF_DEVICE_PARAM, int nDeviceCnt);
'Actual function call
GBIF_DEVICE_PARAM* pGbIF_DEVICE_PARAM = (GBIF_DEVICE_PARAM*)malloc( sizeof(GBIF_DEVICE_PARAM)*(ulNumSensors));
iRet = Acquisition_GbIF_GetDeviceList(pGbIF_DEVICE_PARAM,ulNumSensors);
Here in C++ code he is not sending array of structures as parameter to the function call.
Instead while allocating space in malloc statement, he is allocation the space
for the pointer to structure for total number of sensors detected.
In my case, since I have connected to only one detector, I just allocated space for one structure.
If this is wrong, then please tell me how should I allocate the space for multiple number of sensors connected.
Thanks and Regards,
Susheelss
-
May 11th, 2012, 01:24 PM
#11
Re: Conversion from VC++ to VB.NET
I was slightly wrong about declaring the structure. Use this instead:-
vbnet Code:
'
Public Const GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH = 16
<StructLayout(LayoutKind.Sequential)> _
Public Structure GBIF_DEVICE_PARAM
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _
Public ucMacAddress As String
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _
Public ucIP As String
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _
Public ucSubnetMask As String
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _
Public ucGateway As String
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _
Public ucAdapterIP As String
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _
Public ucAdapterMask As String
Public dwIPCurrentBootOptions As Integer
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=32)> _
Public cManufacturerName As String
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=32)> _
Public cModelName As String
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=32)> _
Public cGBIFFirmwareVersion As String
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=16)> _
Public cDeviceName As String
End Structure
And declare your API as:-
vbnet Code:
<DllImport("YourDll.Dll")> _
Private Shared Function Acquisition_GbIF_GetDeviceLis(<Out()> ByVal dev() As GBIF_DEVICE_PARAM, ByVal devCount As Integer) As Integer
End Function
Make sure that you resize your array based on devCount before passing it into the function. I don;t know the name of the DLL where that function resides so you will have to replace "YourDll.Dll" in my example above with whatever the DLL's name is.
-
May 11th, 2012, 01:25 PM
#12
Re: Conversion from VC++ to VB.NET
 Originally Posted by Susheelss
Here in C++ code he is not sending array of structures as parameter to the function call.
Instead while allocating space in malloc statement, he is allocation the space
for the pointer to structure for total number of sensors detected.
In other words, an array
-
May 11th, 2012, 11:39 PM
#13
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Thanks Mr.Niya for your valuable reply.
As you said I copy pasted the structure and the DLL call in my module.
But it gave the error saying "Methods in a cannot be declared 'shared'". Hence I removed the shared keyword and pasted the DLL call signature in the module.
Then I declared the array of structure based on the device count and the coding done was as follows:
Code:
Dim SensorsNum As Integer = 1
Dim DllCallReturnValue As Integer
Dim pGbIF_DEVICE_PARAM() As GBIF_DEVICE_PARAM
ReDim pGbIF_DEVICE_PARAM(SensorsNum)
Dim myptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pGbIF_DEVICE_PARAM(SensorsNum)))
Marshal.StructureToPtr(pGbIF_DEVICE_PARAM(SensorsNum), myptr, False)
DllCallReturnValue = Acquisition_GbIF_GetDeviceList(Marshal.PtrToStructure(myptr, pGbIF_DEVICE_PARAM(SensorsNum).GetType()), SensorsNum)
But now I'm getting an error saying
" 'Acquisition_GbIF_GetDeviceList' is not declared.It may be inaccessible due to its protection level."
I think the function signature is not matching with the actual function call, as
in the function call I'm sending Pointer to structure as 1st parameter and in signature I am having 1st parameter as array of structure. Structure send as a value(Byval).
Can you please tell me how to resolve this?
Thanks and Regards,
Susheelss.
-
May 11th, 2012, 11:49 PM
#14
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Sorry it was my mistake> I did not see the function call declared as private. I changed it to Public. Now I think It should work. Will get back after testing.
-
May 12th, 2012, 12:07 AM
#15
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Mr.Niya As per your directions I declared the function call as below:
Code:
<DllImport("MyDLL.dll")> Public Function Acquisition_GbIF_GetDeviceList(<Out()> ByVal pGbIF_DEVICE_PARAMS() As GBIF_DEVICE_PARAM, ByVal devCount As Integer) As Integer
End Function
Dim pGbIF_DEVICE_PARAM() As GBIF_DEVICE_PARAM
ReDim pGbIF_DEVICE_PARAM(SensorsNum)
Dim myptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pGbIF_DEVICE_PARAM(SensorsNum)))
Marshal.StructureToPtr(pGbIF_DEVICE_PARAM(SensorsNum), myptr, False)
DllCallReturnValue = Acquisition_GbIF_GetDeviceList(Marshal.PtrToStructure(myptr, pGbIF_DEVICE_PARAM(ulNumSensors).GetType()), SensorsNum)
Now I'm getting Error saying:
"Unable to cast object of type 'GBIF_DEVICE_PARAM' to type 'GBIF_DEVICE_PARAM[]'."
-
May 13th, 2012, 11:03 PM
#16
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Can anybody please suggest me how this Type Casting issue can be resolved and hence to get the Structure members filled through DLL all?
Thanks and Regards,
Susheelss
-
May 14th, 2012, 08:26 AM
#17
Re: Conversion from VC++ to VB.NET
Pass the array as you would pass it to a .Net function. No need to obtain its pointer through the Marshal class. Also, please pay attention to what I said....I told you to replace this <DllImport("MyDLL.dll")>. The MyDll.dll should be the name of the dll file that has your function.
-
May 16th, 2012, 12:18 AM
#18
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Thanks Mr.Niya. The problem is resolved. Thanks for your support. Hope it continues the same way. I was struggling on this function call from past 15 days. Finally it solved because of your help.
Regards,
Susheelss.
-
May 17th, 2012, 09:52 AM
#19
Re: Conversion from VC++ to VB.NET
Do not forget to dimension the array before passing it into the unmanaged function. You would risk invalid memory writes if you don't.
-
May 22nd, 2012, 12:27 AM
#20
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Now that I was able to get all the structure parameters I am struck with another call which is as follows:
Code:
// "HANDLE" in below definition defined as Void pointer in "WinNT.h" file.
typedef void *HANDLE;
typedef HANDLE HACQDESC;
#define GBIF_STRING_DATATYPE unsigned char
HIS_RETURN Acquisition_GbIF_Init(HACQDESC *phAcqDesc,
int nChannelNr,
BOOL bEnableIRQ,
UINT uiRows, UINT uiColumns,
BOOL bSelfInit, BOOL bAlwaysOpen,
long lInitType,
GBIF_STRING_DATATYPE* cAddress);
I am suppose to send the return value of "ucIP" structure member for "cAddress".
But in Vb.NET when I tried the code as below:
Code:
Dim hAcqDesc As IntPtr
Dim bEnableIRQ As Boolean = True
Dim dwRows As UInt32 = 0
Dim dwColumns As UInt32 = 0
Dim bSelfInit As Boolean = True
Dim SET_FALSE As Boolean = False
Const HIS_GbIF_IP = 1
Dim lOpenMode As Long = HIS_GbIF_IP
Dim Detector_ucIP As String
<DllImport("MYDLL.dll")> Public Function Acquisition_GbIF_Init(ByRef HACQDESC As IntPtr, ByVal nChannelNr As Integer, ByVal bEnableIRQ As Boolean, ByVal uiRows As UInt32, ByVal uiColumns As UInt32, ByVal bSelfInit As Boolean, ByVal bAlwaysOpen As Boolean, ByVal lInitType As Long, ByREF cAddress As String) As Integer
DllCallReturnValue = Acquisition_GbIF_Init(hAcqDesc, 0, bEnableIRQ, dwRows, dwColumns, bSelfInit, SET_FALSE, lOpenMode, )
End Function
I am getting an error saying "Unable to fimd the entry point in the DLL".
Can Anybody please help me?????
-
May 22nd, 2012, 12:28 AM
#21
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Now that I was able to get all the structure parameters I am struck with another call which is as follows:
Code:
// "HANDLE" in below definition defined as Void pointer in "WinNT.h" file.
typedef void *HANDLE;
typedef HANDLE HACQDESC;
#define GBIF_STRING_DATATYPE unsigned char
HIS_RETURN Acquisition_GbIF_Init(HACQDESC *phAcqDesc,
int nChannelNr,
BOOL bEnableIRQ,
UINT uiRows, UINT uiColumns,
BOOL bSelfInit, BOOL bAlwaysOpen,
long lInitType,
GBIF_STRING_DATATYPE* cAddress);
I am suppose to send the return value of "ucIP" structure member for "cAddress".
But in Vb.NET when I tried the code as below:
Code:
Dim hAcqDesc As IntPtr
Dim bEnableIRQ As Boolean = True
Dim dwRows As UInt32 = 0
Dim dwColumns As UInt32 = 0
Dim bSelfInit As Boolean = True
Dim SET_FALSE As Boolean = False
Const HIS_GbIF_IP = 1
Dim lOpenMode As Long = HIS_GbIF_IP
Dim Detector_ucIP As String
<DllImport("MYDLL.dll")> Public Function Acquisition_GbIF_Init(ByRef HACQDESC As IntPtr, ByVal nChannelNr As Integer, ByVal bEnableIRQ As Boolean, ByVal uiRows As UInt32, ByVal uiColumns As UInt32, ByVal bSelfInit As Boolean, ByVal bAlwaysOpen As Boolean, ByVal lInitType As Long, ByREF cAddress As String) As Integer
DllCallReturnValue = Acquisition_GbIF_Init(hAcqDesc, 0, bEnableIRQ, dwRows, dwColumns, bSelfInit, SET_FALSE, lOpenMode, )
End Function
I am getting an error saying "Unable to find the entry point in the DLL".
Can Anybody please help me?????
-
May 22nd, 2012, 12:55 PM
#22
Re: Conversion from VC++ to VB.NET
Is MYDLL.dll the actual name of your dll ? In any case, that error occurs when a function cannot be found in the dll. Maybe you spelt it wrong and I believe its also case sensitive.
-
May 22nd, 2012, 11:07 PM
#23
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Thanks Mr.Niya for your reply.
The DLL name name is not the problem as It is the same name.
The VC++ call is like this:
Code:
typedef HANDLE HACQDESC;
#define GBIF_STRING_DATATYPE unsigned char
HIS_RETURN Acquisition_GbIF_Init(HACQDESC *phAcqDesc,int nChannelNr,
BOOL bEnableIRQ, UINT uiRows, UINT uiColumns, BOOL bSelfInit,
BOOL bAlwaysOpen,long lInitType,GBIF_STRING_DATATYPE* cAddress);
The VB.NET code I translated is like this:
Code:
<DllImport("MYDLL.dll")> Public Function Acquisition_GbIF_Init(ByRef HACQDESC As IntPtr, ByVal nChannelNr As Integer, ByVal bEnableIRQ As Boolean, ByVal uiRows As UInt32, ByVal uiColumns As UInt32, ByVal bSelfInit As Boolean, ByVal bAlwaysOpen As Boolean, ByVal lInitType As Long, ByRef cAddress As String) As Integer
End Function
Here I should send be sending the value of "ucIP" which was declared as the structure member as:
Code:
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=GBIF_IP_MAC_NAME_CHAR_ARRAY_LENGTH)> _
Public ucIP As String
I think the problem is in defining the "cAddress" as "string" which instead is defined as "Unsigned Char" in VC++.
Or the other problem could be declaring the Handle "HACQDESC" as Intptr.
Orelse is there any problem in other parameters declaration?
-
May 23rd, 2012, 10:43 AM
#24
Re: Conversion from VC++ to VB.NET
Unable to find the entry point in the DLL has nothing to do with the function's signature. P/Invoke can't find the function at all which means the name maybe wrong. If it were the signature that was wrong then you would get a stack imbalance error. Make sure that you have the right function name.
-
May 25th, 2012, 01:21 AM
#25
Thread Starter
Addicted Member
Re: Conversion from VC++ to VB.NET
Thanks Niya for your Valuable suggestions and replies.
The problem got solved. I replaced the datatype of "lInitType" declared as long to integer and the problem got solved.
-
Feb 17th, 2013, 04:21 PM
#26
New Member
Re: Conversion from VC++ to VB.NET
Suseelss,
Could you please publish the code that worked?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|