Home All Groups Group Topic Archive Search About

Error calling unmanaged DLL

Author
12 Dec 2006 9:28 AM
Woo Mun Foong
Hi,

My program have to call a function inside an unmanaged DLL.

int __stdcall MarsOpen(MARS_CONTROL* pCtl,
    void (__stdcall* CallbackFunction)(MARS_CONTROL* pCtl, int iEvent));

So inside my VB2005 I do this:-

1) Declare a delegate for the Callback
    Public Delegate Function MyCallBack(ByRef MarsControl As MARS_CONTROL,
ByVal iEvent As Integer) As Long

2) Declare an entry point to the DLL Function
    Public Declare Function MarsOpen Lib "MEIBAC.DLL" (ByRef MarsControl As
MARS_CONTROL, ByVal pFunc As MyCallBack) As Integer

3) Code MyCallBack Function inside VB2005
   Public Function MyEventHandle(ByRef aMarsControl As MARS_CONTROL, ByVal
iEvent As Integer) As Long

'Write my stuffs here
End Function

4) Call the MarsOpen Function
intRC = MarsOpen(MarsControl, AddressOf MyEventHandle)

After the call to MarsOpen the programs will gives either one of the three:-
a) Attempted to read or write protected memory. This is often an indication
that other memory is corrupt.
b) The instruction at "0x77d510e6" referenced memory at "0x004d0652". The
memory could not be "read".
c) The instruction at "0x763912e9" referenced memory at "0x004d0652". The
memory could not be "read".


Please help.


Thank You,
mfwoo

Author
12 Dec 2006 5:32 PM
Chris Dunaway
Woo Mun Foong wrote:

Show quoteHide quote
> My program have to call a function inside an unmanaged DLL.
>
> int __stdcall MarsOpen(MARS_CONTROL* pCtl,
>     void (__stdcall* CallbackFunction)(MARS_CONTROL* pCtl, int iEvent));
>
> So inside my VB2005 I do this:-
>
> 1) Declare a delegate for the Callback
>     Public Delegate Function MyCallBack(ByRef MarsControl As MARS_CONTROL,
> ByVal iEvent As Integer) As Long
>
> 2) Declare an entry point to the DLL Function
>     Public Declare Function MarsOpen Lib "MEIBAC.DLL" (ByRef MarsControl As
> MARS_CONTROL, ByVal pFunc As MyCallBack) As Integer
>
> 3) Code MyCallBack Function inside VB2005
>    Public Function MyEventHandle(ByRef aMarsControl As MARS_CONTROL, ByVal
> iEvent As Integer) As Long
>
> 'Write my stuffs here
> End Function

I don't know specifically what your problem, but make sure your
signature for the function in VB.net uses the correct data types.  For
example, the original function uses int for the iEvent argument.  In
VB.Net, you would probably use a Short data type for that because
Integer in VB.Net is 4 bytes whereas int in that function is probably 2
bytes.

I don't know what the MARS_CONTROL structure looks like, but again
double check it's data types and make sure you use the correct
equivalents in VB.Net.

Chris
Author
13 Dec 2006 8:29 AM
Woo Mun Foong
Hi,

MARS_CONTROL structure in its original VB6 is:-

Type MARS_CONTROL
  iLength As Long
  iPollInterval As Long
  iListenInterval As Long
  iInterruptMode As Long
  iSerialPort As Long
  iDenominations As Long
  iSecurity As Long
  iOrientation As Long
  iEscrow As Long
  iAcceptBookmarks As Long
  iBarCode As Long
  iPushMode As Long
  iPowerUpB As Long
  iMaxPollResponseInterval As Long
  iMaxNoResponseInterval As Long
  iLogLevel As Long
  iStatus As Long
  iModel As Long
  iRevision As Long
  iInfo(8) As Long
  iPowerUpC As Long
  iTimerType As Long
End Type

And after converting to VB2005 (By Conversion Wizard) it becomes:-

Public Structure MARS_CONTROL
    Dim iLength As Integer
    Dim iPollInterval As Integer
    Dim iListenInterval As Integer
    Dim iInterruptMode As Integer
    Dim iSerialPort As Integer
    Dim iDenominations As Integer
    Dim iSecurity As Integer
    Dim iOrientation As Integer
    Dim iEscrow As Integer
    Dim iAcceptBookmarks As Integer
    Dim iBarCode As Integer
    Dim iPushMode As Integer
    Dim iPowerUpB As Integer
    Dim iMaxPollResponseInterval As Integer
    Dim iMaxNoResponseInterval As Integer
    Dim iLogLevel As Integer

    ' these fields are returned from the DLL
    Dim iStatus As Integer
    Dim iModel As Integer
    Dim iRevision As Integer
    <VBFixedArray(8)> Dim iInfo() As Integer
    Dim iPowerUpC As Integer
    Dim iTimerType As Integer

    Public Sub Initialize()
        ReDim iInfo(8)
    End Sub
End Structure

The problem is after I made a call to MarsOpen, the next statement I run
will gives  me

"Attempted to read or write protected memory. This is often an indication
that other memory is corrupt."

Any ideas ?

Show quoteHide quote
"Chris Dunaway" wrote:

> Woo Mun Foong wrote:
>
> > My program have to call a function inside an unmanaged DLL.
> >
> > int __stdcall MarsOpen(MARS_CONTROL* pCtl,
> >     void (__stdcall* CallbackFunction)(MARS_CONTROL* pCtl, int iEvent));
> >
> > So inside my VB2005 I do this:-
> >
> > 1) Declare a delegate for the Callback
> >     Public Delegate Function MyCallBack(ByRef MarsControl As MARS_CONTROL,
> > ByVal iEvent As Integer) As Long
> >
> > 2) Declare an entry point to the DLL Function
> >     Public Declare Function MarsOpen Lib "MEIBAC.DLL" (ByRef MarsControl As
> > MARS_CONTROL, ByVal pFunc As MyCallBack) As Integer
> >
> > 3) Code MyCallBack Function inside VB2005
> >    Public Function MyEventHandle(ByRef aMarsControl As MARS_CONTROL, ByVal
> > iEvent As Integer) As Long
> >
> > 'Write my stuffs here
> > End Function
>
> I don't know specifically what your problem, but make sure your
> signature for the function in VB.net uses the correct data types.  For
> example, the original function uses int for the iEvent argument.  In
> VB.Net, you would probably use a Short data type for that because
> Integer in VB.Net is 4 bytes whereas int in that function is probably 2
> bytes.
>
> I don't know what the MARS_CONTROL structure looks like, but again
> double check it's data types and make sure you use the correct
> equivalents in VB.Net.
>
> Chris
>
>
Author
13 Dec 2006 1:55 PM
Chris Dunaway
Woo Mun Foong wrote:

You have this function:

> int __stdcall MarsOpen(MARS_CONTROL* pCtl,
>    void (__stdcall* CallbackFunction)(MARS_CONTROL* pCtl, int iEvent));

but this VB.Net signature:

>  Public Declare Function MarsOpen Lib "MEIBAC.DLL" (ByRef MarsControl As
> MARS_CONTROL, ByVal pFunc As MyCallBack) As Integer

Assuming that MARS_CONTROL is correct, the return type you have here is
Integer.  It seems like it should be Short since the original is int
(as used in VB6) which is 16 bit.  Whereas Integer in VB.Net is 32
bits.

Double check your other signatures as well.  You have the callback
returning a Long, which is 64 bits in .Net.  Is that correct?

Chris