Hi,
I'm upgrading a VB6 app to VB.net and I'm having a problem with a call to a
function provided in a DLL.
The function takes the address of a structure which it will fill in with
values.
I get an error:
----------------
An unhandled exception of type 'System.NullRef erenceException ' occured in
Project1.exe
Additional Information: Object reference not set to an instance of an object.
----------------
Based on the UPGRADE_TODOs etc that the upgrade wizard put in my code, I
suspect the problem is with marshaling the VB struct to the unmanaged
function.
Below is a (rather long) description of how the VB looked in VB6, what the
wizard turned it into, the C signature of the function, and some of the
things I've tried.
I would be very grateful for suggestions on how to pass the structure
correctly or where to find a good explanation of the rules. Thanks!
in VB6, it was like this
' the structure that the function takes as a parameter
Public Type NifInterfaceInf o ' Interface Infor structure
interfaceName(N IF_NAME_LEN) As Byte
DeviceID(DEV_ID _SIZE) As Byte
End Type
' the declaration of the function that takes the NifInterfaceInf o struct
Declare Function nifGetInterface List Lib "nifbstd" (ByVal session As Long,
ByRef numIntf As Integer, ByRef info As NifInterfaceInf o) As Long
' an example of a subroutine which invokes the function
Private Sub OpenSess()
' Open a fieldbus Session
Ret (nifOpenSession (vbNull, SessionDesc))
' Pass the max interface number to function "nifGetInterfac eList"
NoOfInterfaces = MAX_INTERFACES
' Get all the interface information
Ret (nifGetInterfac eList(SessionDe sc, NoOfInterfaces, InterfaceInfo(0 )))
For i = 0 To NoOfInterfaces - 1
' The interfaceName and DeviceID are array of byte, need to be
converted by function "getString"
ListInterface.A ddItem getString(Inter faceInfo(i).int erfaceName)
Next
End Sub
The upgrade wizard did this:
Public Structure NifInterfaceInf o ' Interface Infor structure
<VBFixedArray(N IF_NAME_LEN)> Dim interfaceName() As Byte
<VBFixedArray(D EV_ID_SIZE)> Dim DeviceID() As Byte
'UPGRADE_TODO: "Initialize " must be called to initialize instances
of this structure. Click for more:
'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?ke yword="vbup1026 "'
Public Sub Initialize()
ReDim interfaceName(N IF_NAME_LEN)
ReDim DeviceID(DEV_ID _SIZE)
End Sub
End Structure
'UPGRADE_WARNIN G: Structure NifInterfaceInf o may require marshalling
attributes to be passed as an argument in this Declare statement. Click for
more: 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?ke yword="vbup1050 "'
Declare Function nifGetInterface List Lib "nifbstd" (ByVal session As
Integer, ByRef numIntf As Short, ByRef info As NifInterfaceInf o) As Integer
Private Sub OpenSess()
' Open a fieldbus Session
Ret((nifOpenSes sion(VariantTyp e.Null, SessionDesc)))
' Pass the max interface number to function "nifGetInterfac eList"
NoOfInterfaces = MAX_INTERFACES
' Get all the interface information
Ret((nifGetInte rfaceList(Sessi onDesc, NoOfInterfaces,
InterfaceInfo(0 ))))
For i = 0 To NoOfInterfaces - 1
' The interfaceName and DeviceID are array of byte, need to be
converted by function "getString"
ListInterface.I tems.Add(getStr ing(InterfaceIn fo(i).interface Name))
Next
End Sub
--------------
The underlying C declarations are like this:
typedef struct nifInterfaceInf o_t {
char interfaceName[NIF_NAME_LEN];
char deviceID[DEV_ID_SIZE + 1];
} nifInterfaceInf o_t;
extern nifError_t nifGetInterface List(nifDesc_t ud, int16 *numInterfaces,
nifInterfaceInf o_t *info);
--------------
As suggested by the UPGRADE_TODO vbup1026, I added a call to Initialize()
like this:
Private Sub OpenSess()
' Open a fieldbus Session
Ret((nifOpenSes sion(VariantTyp e.Null, SessionDesc)))
' Pass the max interface number to function "nifGetInterfac eList"
NoOfInterfaces = MAX_INTERFACES
InterfaceInfo.I nitialize()
For i = InterfaceInfo.G etLowerBound(0) To
InterfaceInfo.G etUpperBound(0)
InterfaceInfo(i ).Initialize()
Next
' Get all the interface information
Ret((nifGetInte rfaceList(Sessi onDesc, NoOfInterfaces,
InterfaceInfo(0 ))))
For i = 0 To NoOfInterfaces - 1
' The interfaceName and DeviceID are array of byte, need to be
converted by function "getString"
ListInterface.I tems.Add(getStr ing(InterfaceIn fo(i).interface Name))
Next
End Sub
I examined InterfaceInfo in the debugger, and it looks ok following the
call(s) to Initialize().
The call to nifGetInterface List fails with an error
----------------
An unhandled exception of type 'System.NullRef erenceException ' occured in
Project1.exe
Additional Information: Object reference not set to an instance of an object.
----------------
if I add this
<StructLayout ( LayoutKind.Sequ ential, CharSet:=CharSe t.ANSI)>
to the structure declaration, I get the same error.
If I add MarshalAs attributes (as suggested by UPGRADE_WARNING : Structure
NifInterfaceInf o may require marshalling attributes to be passed as an
argument in this Declare statement. Click for more:
'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?ke yword="vbup1050 "):
<StructLayout(L ayoutKind.Seque ntial, CharSet:=CharSe t.Ansi)> _
Public Structure NifInterfaceInf o ' Interface Infor structure
<VBFixedArray(N IF_NAME_LEN), MarshalAs(Unman agedType.ByValT Str,
SizeConst:=NIF_ NAME_LEN)> Dim interfaceName() As Byte
<VBFixedArray(D EV_ID_SIZE), MarshalAs(Unman agedType.ByValT Str,
SizeConst:=DEV_ ID_SIZE)> Dim DeviceID() As Byte
'UPGRADE_TODO: "Initialize " must be called to initialize instances
of this structure. Click for more:
'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?ke yword="vbup1026 "'
Public Sub Initialize()
ReDim interfaceName(N IF_NAME_LEN)
ReDim DeviceID(DEV_ID _SIZE)
End Sub
End Structure
then I get error:
----------------
An unhandled exception of type 'System.TypeLoa dException' occured in
Project1.exe
Additional Information: Can not marshal field interfaceName of type
NifInterfaceInf o: This type can not be marshaled as a structure field
----------------
Anyone have suggestions for the right way to pass a VB.net struct containing
fixed length arrays to a DLL?
Jun 12 '06
10 4993
David Fort (donotspam) wrote: Here is the magic syntax:
<StructLayout(L ayoutKind.Seque ntial)> _ Public Structure NifInterfaceInf o <MarshalAs(Unma nagedType.ByVal Array, SizeConst:=NIF_ NAME_LEN + 1)> _ Public interfaceName As Byte() <MarshalAs(Unma nagedType.ByVal Array, SizeConst:=DEV_ ID_SIZE + 1)> _ Public DeviceID As Byte() Public Sub Initialize() ReDim interfaceName(N IF_NAME_LEN) ReDim DeviceID(DEV_ID _SIZE) End Sub End Structure
Declare Function nifGetInterface List Lib "nifbstd" (ByVal session As Integer, ByRef numIntf As Short, <Out()> ByVal info As NifInterfaceInf o()) As Integer
Public InterfaceInfo(M AX_INTERFACES) As NifInterfaceInf o
and call it like this: nifGetInterface List(SessionDes c, NoOfInterfaces, InterfaceInfo)
So, the only change from Tom's last suggestion was the addition of <Out()> in the function declaration on the third argument.
David - I'm glad you got this figured out. I've been busy the last
couple of days, and wasn't able to respond.
--
Tom Shelton [MVP] This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Ivan |
last post by:
Hi All,
I have a problem with marshaling complex structures (containing numbers,
strings, arrays of another structures) to native C function in dll.
I have already posted same question to .compactframework thread, but nobody
helped.
main problem is that I have tried all the workarounds I have found in the
Inet but nothing worked...
I tried passing IntPtr, Byte Arrays, Serialisation, even used OpenNETCF, but
|
by: Eric Hendriks |
last post by:
// In an unmanaged DLL the following function must be called:
// int VFGeneralize(const BYTE * const * features);
// "features" parameter is supposed to be an array of byte arrays.
// function is Marshaled as follows:
static extern int VFGeneralize(byte features);
In C# I have the following:
// Allocate memory to store "Count" references to byte arrays
|
by: kevin |
last post by:
Hi
I have a C struct that is of the following
typedef struct{
DWORD num_conversions; ...
short *sample_values;
....
|
by: Ivan |
last post by:
Hi All,
I have a problem with marshaling complex structures (containing numbers,
strings, arrays of another structures) to native C function in dll.
I have already posted same question to .compactframework thread, but nobody
helped.
main problem is that I have tried all the workarounds I have found in the
Inet but nothing worked...
I tried passing IntPtr, Byte Arrays, Serialisation, even used OpenNETCF, but
|
by: nicewenyan |
last post by:
I want to pass a managed c# byte (8 bit) array into a unmanaged c++
function:
extern "C" void AddData(unsigned int* data);
I use P/Invoke on managed side to do the marshaling as following:
public static extern int AddData(IntPtr data);
| |
by: cleanrabbit |
last post by:
Hello!
I hate having to do this, because im almost certain there is someone in the world that has come across this problem and i just havent found their solution yet, so i do appologise if this has already been covered.
I have been trying to learn c# as fast as possible in the last month and in doing so i have been re-visiting old C/C++ problems and trying to overcome them in C#.
What i have is a very complex serise of structures. Id...
|
by: RobbieJosefson |
last post by:
I want to marshal a structure containing a variable length array which will be populated within a C++ dll. the structure is the following
Public Structure myStructure{
Public int size;
Public myInsideStructure inside;
};
The myInsideStructure just contains a string. The problem is the size of the myInsideStructure wont be known until runtime and the size variable will have the number of posts in the myInsideStructure structure...
|
by: Charming12 |
last post by:
Hi All,
I have a strange problem and due to my inefficiency with IntPtr i am unable to figure it out.
I have an structure something like:
public struct Detail
{
public int age;
public Detail(int _age)
|
by: Charming12 |
last post by:
Hi All,
This is a problem which is eating my head from several days.
I have a structure which contains an array of elements as
public byte pinNumbers;
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
| |
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |