Home All Groups Group Topic Archive Search About
Author
4 Jan 2006 3:15 PM
Bob Simoneau
I am trying to get a C DLL to work with VB.NET 2005. Below is the original
header, my conversion, and test code.  There is no error, but
RVERSION_RESP.version returns empty.  I must be missing something.  Thanks
in advance for any help.


#define REQUEST_DECLINED -2

typedef struct rversion_parms_set_1    RVERSION_PARMS;
typedef struct rversion_resp_set_1     RVERSION_RESP;

#pragma pack(1)

struct rversion_parms_set_1
{
int  size;          /* REQUIRED Size of structure */
};

struct rversion_resp_set_1
{
int  size;   /* REQUIRED Size of structure */
int  return_code;  /* = 0 if no error, != 0 if error */
char return_text[200];  /* Contains error text if return code != 0 */
char version[11];  /* DLL version */
};


#pragma pack()


_declspec(dllexport) extern void rversion(RVERSION_PARMS *rversion_parms,
RVERSION_RESP *rversion_resp);



Module Module1
    Public Structure TRVERSION_PARMS
        Dim size As Integer  ' REQUIRED Size of structure
    End Structure

    Public Structure TRVERSION_RESP
        Dim size As Short ' REQUIRED Size of structure
        Dim return_code As Short ' 0 if ( no error, != 0 if ( error
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=200)> _
        Dim return_text() As Char   ' Contains error text if return code !=
0
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=11)> _
        Dim version() As Char  ' DLL version
    End Structure

    Public RVERSION_PARMS As TRVERSION_PARMS
    Public RVERSION_RESP As TRVERSION_RESP

    Public Declare Function rversion Lib "c:\remotapi.dll" (ByRef
RVERSION_PARMS As TRVERSION_PARMS, ByRef RVERSION_RESP As TRVERSION_RESP) As
Integer

End Module


Test
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
        RVERSION_PARMS.size = Marshal.SizeOf(RVERSION_PARMS)
        RVERSION_RESP.size = Marshal.SizeOf(RVERSION_RESP)
        rversion(RVERSION_PARMS, RVERSION_RESP)
        If (RVERSION_RESP.return_code <> 0) Then
            TextBox1.Text = "RVERSION ERROR: " & RVERSION_RESP.return_text
        Else
            TextBox1.Text = "RVERSION: " & RVERSION_RESP.version
        End If
    End Sub

Author
5 Jan 2006 7:47 AM
Peter Huang" [MSFT]
Hi Bob,

The int in C++ means a 32bit data type.
But the Short in VB.NET is 16bit data type.

So I think we need to change the definition in the VB.NET signature.
Here is what works at my side for your reference.
    Public Structure TRVERSION_PARMS
        Dim size As Integer  ' REQUIRED Size of structure
    End Structure

    Public Structure TRVERSION_RESP
        Dim size As Integer ' REQUIRED Size of structure
        Dim return_code As Integer ' 0 if ( no error, != 0 if ( error
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=200)> _
        Dim return_text() As Char   ' Contains error text if return code !=
0
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=11)> _
        Dim version() As Char  ' DLL version
    End Structure

    Public RVERSION_PARMS As TRVERSION_PARMS
    Public RVERSION_RESP As TRVERSION_RESP

    Public Declare Function fnTestDLL Lib "TestDLL.dll" (ByRef
RVERSION_PARMS As TRVERSION_PARMS, ByRef RVERSION_RESP As TRVERSION_RESP)
As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
        RVERSION_PARMS.size = Marshal.SizeOf(RVERSION_PARMS)
        RVERSION_RESP.size = Marshal.SizeOf(RVERSION_RESP)
        MsgBox(fnTestDLL(RVERSION_PARMS, RVERSION_RESP).ToString())
        If (RVERSION_RESP.return_code <> 0) Then
            TextBox1.Text = "RVERSION ERROR: " & RVERSION_RESP.return_text
        Else
            TextBox1.Text = "RVERSION: " & RVERSION_RESP.version
        End If
    End Sub


[C++]
TESTDLL_API int fnTestDLL(RVERSION_PARMS *rversion_parms, RVERSION_RESP
*rversion_resp)
{
    rversion_resp->return_code = 0;
    strcpy(rversion_resp->return_text,"Hello");
    strcpy(rversion_resp->version,"World");
    return 42;
}
ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

// This class is exported from the TestDLL.dll
class TESTDLL_API CTestDLL {
public:
    CTestDLL(void);
    // TODO: add your methods here.
};

#define REQUEST_DECLINED -2

typedef struct rversion_parms_set_1    RVERSION_PARMS;
typedef struct rversion_resp_set_1     RVERSION_RESP;

#pragma pack(1)

struct rversion_parms_set_1
{
int  size;          /* REQUIRED Size of structure */
};

struct rversion_resp_set_1
{
int  size;   /* REQUIRED Size of structure */
int  return_code;  /* = 0 if no error, != 0 if error */
char return_text[200];  /* Contains error text if return code != 0 */
char version[11];  /* DLL version */
};


#pragma pack()


extern TESTDLL_API int nTestDLL;

extern "C" TESTDLL_API int fnTestDLL(RVERSION_PARMS *rversion_parms,
RVERSION_RESP *rversion_resp);



Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
5 Jan 2006 3:30 PM
Bob Simoneau
I now get this response from the DLL;
Rversion response structure has bad size.

Here is the function call:
Public Declare Function rversion Lib "c:\remotapi.dll" (ByRef RVERSION_PARMS
As TRVERSION_PARMS, ByRef RVERSION_RESP As TRVERSION_RESP) As Integer

There is something going on a am unaware of, if I write the structure in C
or Delphi, it is 219 bytes long, and the DLL works. However in VB.net the
structure is 220. If I lower the SizeConst to 198 vise 199, the structure
size drops to 216. I tried using byte instead, and got the same result. I am
lost..... Notice the packed record in Delphi, and the #pragma pack(1) in the
C header.  Could this have something to do with it?

>    Public Structure TRVERSION_RESP
>        Dim size As Integer ' REQUIRED Size of structure
>        Dim return_code As Integer ' 0 if  no error, != 0 if  error
>        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=199)> _
>        Dim return_text() As Char   ' Contains error text if return code !=
> 0
>        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
>        Dim version() As Char  ' DLL version
>    End Structure

This stucture in Delphi as a size of 219 and works with the DLL

> type
>  TRVERSION_RESP = packed record
>    size: Integer; // REQUIRED Size of structure
>    return_code: Integer; // 0 if no error, != 0 if error
>    return_text: array[0..199] of Char; // Contains error text if return
> code != 0
>    version: array[0..10] of Char; // DLL version
>  end;

Here is the original C header declaration.

Show quoteHide quote
> #pragma pack(1)

> struct rversion_resp_set_1
> {
>  int  size;   /* REQUIRED Size of structure */
>  int  return_code;  /* = 0 if no error, != 0 if error */
>  char return_text[200];  /* Contains error text if return code != 0 */
>  char version[11];  /* DLL version */
> };
Author
6 Jan 2006 2:48 AM
Peter Huang" [MSFT]
Hi Bob,

Have you tried my code in my last post?
Because that works at my side, if we test on your side, it will help us to
isolate the problem.

For your comment about the size of the structure.
I think it may be align problem.
align (C++)  
http://msdn2.microsoft.com/en-us/library/83ythb65.aspx

Also in .NET we have a similar attribute StructLayoutAttribute.Pack Field,
you may try to change them to see if that will help you.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfsystemruntimeinteropservicesstructlayoutattributeclasspacktopic.asp

If that still did not works for you, can you send me a reproduce
sample?(C++ and VB.NET code including the source code, I am not familar
with delphi)
You can reach me by removing "online" from my email address.


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
6 Jan 2006 1:39 PM
Bob Simoneau
I did run your example, and it worked. Thank you so much for your help. I
finally achieved success by adding the line below to the top of the
structure. You hit it right on the head, it was an align problem. The pack=1
solved it.

Successful Line added.

<StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Ansi)> _

Show quoteHide quote
""Peter Huang" [MSFT]" <v-phu***@online.microsoft.com> wrote in message
news:$fkwBvmEGHA.3696@TK2MSFTNGXA02.phx.gbl...
> Hi Bob,
>
> Have you tried my code in my last post?
> Because that works at my side, if we test on your side, it will help us to
> isolate the problem.
>
> For your comment about the size of the structure.
> I think it may be align problem.
> align (C++)
> http://msdn2.microsoft.com/en-us/library/83ythb65.aspx
>
> Also in .NET we have a similar attribute StructLayoutAttribute.Pack Field,
> you may try to change them to see if that will help you.
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
> frlrfsystemruntimeinteropservicesstructlayoutattributeclasspacktopic.asp
>
> If that still did not works for you, can you send me a reproduce
> sample?(C++ and VB.NET code including the source code, I am not familar
> with delphi)
> You can reach me by removing "online" from my email address.
>
>
> Best regards,
>
> Peter Huang
> Microsoft Online Partner Support
>
> Get Secure! - www.microsoft.com/security
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
Author
9 Jan 2006 3:20 AM
Peter Huang" [MSFT]
Hi Bob,

Thanks for your update.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.