DLL function works from VB6 and not from VB.NET - HELP!

J

James Radke

Hello,

We are currently using a user DLL that when working in VB 6.0 has a user
defined type as a parameter.

Now we are trying to use the same DLL from a vb.net application and are
having some problems getting it to work and we don't know why. Basically
the function is accepting the parameters, and then returning an error and
never performing the update.

Below you will find both the VB6 dll function and user defined type
definition, followed by the VB.NET (2003 version) dll function and structure
definition that we are using. Unfortunately I do not have the source code to
the DLL, so I don't know how the fields are defined in there.

Can someone tell me what may be defined incorrectly, or how I can figure out
why the call is not working? Also, I have tried every type of
UnmanagedType.<string type> in the definitions within the structure (i.e.
LPSTR, etc)

One of these should work, shouldn't they? What else could be happening?

Any help would be appreciated!

Jim

==== Begin VB 6 dll function and type definition ===
Declare Function AddSalesOrderLineItem Lib "MAXORDR2.DLL" (ByVal OH As Long,
Soedet As SOEDetItem) As Integer

Type SODetail
ORDNUM28 As String * 6 ' String
LINNUM28 As String * 2 ' String
DELNUM28 As String * 2 ' String
STATUS28 As String * 1 ' String
CUSTID28 As String * 7 ' String
PRTNUM28 As String * 15 ' String
EDILIN28 As String * 6 ' String
TAXABL28 As String * 1 ' String
GLXREF28 As String * 32 ' String
CURDUE28 As Long ' Btrieve Date
FILL0128 As String * 2 ' String
ORGDUE28 As Long ' Btrieve Date
FILL0228 As String * 2 ' String
CUSDUE28 As Long ' Btrieve Date
FILL0328 As String * 2 ' String
SHPDTE28 As Long ' Btrieve Date
FILL0428 As String * 2 ' String
SLSUOM28 As String * 2 ' String
REFRNC28 As String * 25 ' String
PRICE28 As Double ' IEEE Float
ORGQTY28 As Double ' IEEE Float
CURQTY28 As Double ' IEEE Float
BCKQTY28 As Double ' IEEE Float
SHPQTY28 As Double ' IEEE Float
CURSHP28 As Double ' IEEE Float
DUEQTY28 As Double ' IEEE Float
INVQTY28 As Double ' IEEE Float
DISC28 As Single ' IEEE Float
STYPE28 As String * 2 ' String
PRNT28 As String * 1 ' String
AKPRNT28 As String * 1 ' String
STK28 As String * 8 ' String
COCFLG28 As String * 3 ' String
FORCUR28 As Double ' IEEE Float
HSTAT28 As String * 1 ' String
SLSREP28 As String * 7 ' String
COMMIS28 As Single ' IEEE Float
DRPSHP28 As String * 10 ' String
QUMQTY28 As Single ' IEEE Float
TAXCDE128 As String * 7 ' String
TAX128 As Double ' IEEE Float
TAXCDE228 As String * 7 ' String
TAX228 As Double ' IEEE Float
TAXCDE328 As String * 7 ' String
TAX328 As Double ' IEEE Float
MCOMP28 As String * 3 ' String
MSITE28 As String * 3 ' String
UDFKEY28 As String * 15 ' String
UDFREF28 As String * 25 ' String
DEXPFLG28 As String * 1 ' String (adChar)
FILLER28 As String * 24 ' String
End Type
====== END VB 6 Type definition
====== Begin VB.NET DLL function and Structure Definition =======
Declare Function AddSalesOrderLineItem Lib "MAXORDR2.DLL" (ByVal OH As
Int32, ByRef Soedet As SOEDetItem) As Short

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure SOEDetItem
<MarshalAs(UnmanagedType.LPStr, SizeConst:=6)> Public ORDNUM As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=2)> Public LINNUM As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=2)> Public DelNum As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=1)> Public STATUS As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=7)> Public CUSTID As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=15)> Public PRTNUM As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=6)> Public EDILIN As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=1)> Public TAXABL As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=32)> Public GLXREF As
String
Public CURDUE As Int32
<MarshalAs(UnmanagedType.LPStr, SizeConst:=2)> Public FILL01 As
String
Public ORGDUE As Int32
<MarshalAs(UnmanagedType.LPStr, SizeConst:=2)> Public FILL02 As
String
Public CUSDUE As Int32
<MarshalAs(UnmanagedType.LPStr, SizeConst:=2)> Public FILL03 As
String
Public SHPDTE As Int32
<MarshalAs(UnmanagedType.LPStr, SizeConst:=2)> Public FILL04 As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=2)> Public SLSUOM As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=25)> Public REFRNC As
String
Public PRICE As Double
Public ORGQTY As Double
Public CURQTY As Double
Public BCKQTY As Double
Public SHPQTY As Double
Public CURSHP As Double
Public DUEQTY As Double
Public INVQTY As Double
Public DISC As Single
<MarshalAs(UnmanagedType.LPStr, SizeConst:=2)> Public STYPE As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=1)> Public PRNT As String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=1)> Public AKPRNT As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=8)> Public STK As String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=3)> Public COCFLG As
String
Public FORCUR As Double
<MarshalAs(UnmanagedType.LPStr, SizeConst:=1)> Public HSTAT As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=7)> Public SLSREP As
String
Public COMMIS As Single
<MarshalAs(UnmanagedType.LPStr, SizeConst:=10)> Public DRPSHP As
String
Public QUMQTY As Single
<MarshalAs(UnmanagedType.LPStr, SizeConst:=7)> Public TAXCDE1 As
String
Public TAX1 As Double '# TAX AMOUNT 1
<MarshalAs(UnmanagedType.LPStr, SizeConst:=7)> Public TAXCDE2 As
String
Public TAX2 As Double
<MarshalAs(UnmanagedType.LPStr, SizeConst:=7)> Public TAXCDE3 As
String
Public TAX3 As Double '$ TAX AMOUNT 3
<MarshalAs(UnmanagedType.LPStr, SizeConst:=3)> Public MCOMP As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=3)> Public MSITE As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=15)> Public UDFKEY As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=25)> Public UDFREF As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=1)> Public DEXPFLG As
String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=25)> Public FILLER As
String
End Structure
==== End vb.net struct definition ======
 
M

Mattias Sjögren

James,
Can someone tell me what may be defined incorrectly, or how I can figure out
why the call is not working? Also, I have tried every type of
UnmanagedType.<string type> in the definitions within the structure (i.e.
LPSTR, etc)

Including ByValTStr? That's the one you should use.



Mattias
 
B

Brian W

Have you tried declaring the type members as StringBuilder instead of
String? Also, when you do this get rid of the UnmanagedType.LPStr.

HTH
Brian W
 
J

James Radke

Brian,

You can't use a stringbuilder class within a structure statement; or at
least I haven't been able to find a way....

Jim
 
M

Mattias Sjögren

Where do I add that?

Change

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

to

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



Mattias
 
B

Brian W

Check out this topic in help and see if it helps your situation

Structure may require marshalling attributes to be passed as an argument in
this Declare statement
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003JUL.1033/vbcon/html/vbup1050.htm
 
J

James Radke

Matthias,

Nope.. That does not correct the issue either. It's strange because when I
use the ByValTStr, it gives me a 'duplicate record added' message.. but when
I use LPStr it successfully completes, yet the record is never added.....

Any other suggestions?

Jim
 
P

Peter Huang

Hi James,

You may try the declare as follows.

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=1)> _
Private Structure SODetail
<VBFixedString(6),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=6)> Public ORDNUM28 As String ' String
<VBFixedString(2),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=2)> Public LINNUM28 As String ' String
<VBFixedString(2),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=2)> Public DELNUM28 As String ' String
<VBFixedString(1),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=1)> Public STATUS28 As String ' String
<VBFixedString(7),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=7)> Public CUSTID28 As String ' String
<VBFixedString(15),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=15)> Public PRTNUM28 As String ' String
<VBFixedString(6),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=6)> Public EDILIN28 As String ' String
<VBFixedString(1),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=1)> Public TAXABL28 As String ' String
<VBFixedString(32),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=32)> Public GLXREF28 As String ' String
Dim CURDUE28 As Integer ' Btrieve Date
<VBFixedString(2),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=2)> Public FILL0128 As String ' String
Dim ORGDUE28 As Integer ' Btrieve Date
<VBFixedString(2),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=2)> Public FILL0228 As String ' String
Dim CUSDUE28 As Integer ' Btrieve Date
<VBFixedString(2),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=2)> Public FILL0328 As String ' String
Dim SHPDTE28 As Integer ' Btrieve Date
<VBFixedString(2),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=2)> Public FILL0428 As String ' String
<VBFixedString(2),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=2)> Public SLSUOM28 As String ' String
<VBFixedString(25),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=25)> Public REFRNC28 As String ' String
Dim PRICE28 As Double ' IEEE Float
Dim ORGQTY28 As Double ' IEEE Float
Dim CURQTY28 As Double ' IEEE Float
Dim BCKQTY28 As Double ' IEEE Float
Dim SHPQTY28 As Double ' IEEE Float
Dim CURSHP28 As Double ' IEEE Float
Dim DUEQTY28 As Double ' IEEE Float
Dim INVQTY28 As Double ' IEEE Float
Dim DISC28 As Single ' IEEE Float
<VBFixedString(2),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=2)> Public STYPE28 As String ' String
<VBFixedString(1),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=1)> Public PRNT28 As String ' String
<VBFixedString(1),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=1)> Public AKPRNT28 As String ' String
<VBFixedString(8),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=8)> Public STK28 As String ' String
<VBFixedString(3),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=3)> Public COCFLG28 As String ' String
Dim FORCUR28 As Double ' IEEE Float
<VBFixedString(1),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=1)> Public HSTAT28 As String ' String
<VBFixedString(7),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=7)> Public SLSREP28 As String ' String
Dim COMMIS28 As Single ' IEEE Float
<VBFixedString(10),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=10)> Public DRPSHP28 As String ' String
Dim QUMQTY28 As Single ' IEEE Float
<VBFixedString(7),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=7)> Public TAXCDE128 As String ' String
Dim TAX128 As Double ' IEEE Float
<VBFixedString(7),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=7)> Public TAXCDE228 As String ' String
Dim TAX228 As Double ' IEEE Float
<VBFixedString(7),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=7)> Public TAXCDE328 As String ' String
Dim TAX328 As Double ' IEEE Float
<VBFixedString(3),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=3)> Public MCOMP28 As String ' String
<VBFixedString(3),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=3)> Public MSITE28 As String ' String
<VBFixedString(15),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=15)> Public UDFKEY28 As String ' String
<VBFixedString(25),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=25)> Public UDFREF28 As String ' String
<VBFixedString(1),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=1)> Public DEXPFLG28 As String ' String
(adChar)
<VBFixedString(24),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=24)> Public FILLER28 As String ' String
End Structure

Or change the Pack attribute to 8 for test.

Can you modify your code as simple as possible for me to test the project?
also please send me the dll.

You may reach me by removing the online from my email address.

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.
--------------------
Reply-To: "James Radke" <[email protected]>
From: "James Radke" <[email protected]>
References: <e34#[email protected]>
<#[email protected]>
<[email protected]>
<[email protected]>
Subject: Re: DLL function works from VB6 and not from VB.NET - HELP!
Date: Thu, 13 Nov 2003 16:47:38 -0600
Lines: 33
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
Message-ID: <#[email protected]>
Newsgroups: microsoft.public.dotnet.languages.vb
NNTP-Posting-Host: cpe-24-167-241-101.wi.rr.com 24.167.241.101
Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP09.phx.gbl
Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.vb:156683
X-Tomcat-NG: microsoft.public.dotnet.languages.vb

Matthias,

Nope.. That does not correct the issue either. It's strange because when I
use the ByValTStr, it gives me a 'duplicate record added' message.. but when
I use LPStr it successfully completes, yet the record is never added.....

Any other suggestions?

Jim
 
P

Peter Huang

Hi James,

I have another suggestion for you.
You may make a small VB6 sample app that uses the structure and works
successfully. And then run that application through the migration tool(VB
to VB.NET upgrate Wizard) and see if that works.

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.
 
G

Guest

Hello,

I am trying to locate a tutorial that explains how to handle the downloading
of files via the http protocol within a vb application. I have an old
program I wrote in Macromedia Director and I need to recreate it's
functionality within VB.net.

One of the main components of this project is it's ability to
upload/download file data using the http protocol.

I am very new at VB development and am curious as to the handling of
asynchronous network operations are handled within VB.

Macromedia Director uses a frame based/timeline metaphor for adding code etc
whilst VB.net uses forms. In Director I make my http call in frame 10 like
this:

global gNetID
on exitframe me
gNetID = getNetText (http://myserver.com/mytext.txt)
end

I then have Director loop in frame 12 single frame testing the condition of
gNetID until it returns either an error message or the text. It looks
something like this:

global gNetID
on exitframe me
if (netDone(gNetID) = TRUE) and (netError(gNetID) = "OK") then
member("Display Text").text = netTextResult()
go to frame "display results"
else
go to the frame
end if
end

I assume that this type of transaction can be accomplished in VB.net I am
just at a loss for finding an example to study.

Any tutorials out there for this type of thing? I've checked google,
codehound, vbaccelerator, etc...looking for "downloading file techniques"
and nothing.

Many thanks in advance,

devin M. arnold
 
P

Peter Huang

Hi,

According to the C Hearder file, I write a DLL as follows.

[LegacyDLL.dll]
#include "Soedet.h"
SHORT __declspec (dllexport) __stdcall TestStruct(long lSize,SOEDETITEM_PTR
pSDItem)
{
return 0;
}


And I write the Vb.NET declaration as follows which will pass the whole
structure to the C DLL correct on my machine. You may have a try to see if
that works for you.

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure SOEDetItem
<MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=6)> Public ORDNUM() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public LINNUM() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public DELNUM() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public STATUS() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public CUSTID() As Char '
String
<VBFixedString(15), MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=15)> Public PRTNUM() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=6)> Public EDILIN() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public TAXABL() As Char '
String
<VBFixedString(32), MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=32)> Public GLXREF() As Char '
String
Dim CURDUE As Integer ' Btrieve Date
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public FILL01() As Char '
String
Dim ORGDUE As Integer ' Btrieve Date
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public FILL02() As Char '
String
Dim CUSDUE As Integer ' Btrieve Date
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public FILL03() As Char '
String
Dim SHPDTE As Integer ' Btrieve Date
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public FILL04() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public SLSUOM() As Char '
String
<VBFixedString(25), MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=25)> Public REFRNC() As Char '
String
Dim PRICE As Double ' IEEE Float
Dim ORGQTY As Double ' IEEE Float
Dim CURQTY As Double ' IEEE Float
Dim BCKQTY As Double ' IEEE Float
Dim SHPQTY As Double ' IEEE Float
Dim CURSHP As Double ' IEEE Float
Dim DUEQTY As Double ' IEEE Float
Dim INVQTY As Double ' IEEE Float
Dim DISC As Single ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public STYPE() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public PRNT() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public AKPRNT() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=8)> Public STK() As Char ' String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=3)> Public COCFLG() As Char '
String
Dim FORCUR As Double ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public HSTAT() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public SLSREP() As Char '
String
Dim COMMIS As Single ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=10)> Public DRPSHP() As Char '
String
Dim QUMQTY As Single ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public TAXCDE1() As Char '
String
Dim TAX1 As Double ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public TAXCDE2() As Char '
String
Dim TAX2 As Double ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public TAXCDE3() As Char '
String
Dim TAX3 As Double ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=3)> Public MCOMP() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=3)> Public MSITE() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=15)> Public UDFKEY() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=25)> Public UDFREF() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public DEXPFLG() As Char '
String (adChar)
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=24)> Public FILLER() As Char '
String
End Structure
Declare Function TestStruct Lib "LegacyDLL.dll" (ByVal OH As Int32,
ByRef prt As SOEDetItem) As Short

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim uSODet As New SOEDetItem
Dim dteToday As Date
dteToday = Now

'Initialize all the strings to the proper length
With uSODet
.ORDNUM = New String(" ", 6)
.LINNUM = New String(" ", 2)
.DELNUM = New String(" ", 2)
.STATUS = New String(" ", 1)
.CUSTID = New String(" ", 7)
.PRTNUM = New String(" ", 15)
.EDILIN = New String(" ", 6)
.TAXABL = New String(" ", 1)
.GLXREF = New String(" ", 32)
.FILL01 = New String(" ", 2)
.FILL02 = New String(" ", 2)
.FILL03 = New String(" ", 2)
.FILL04 = New String(" ", 2)
.SLSUOM = New String(" ", 2)
.REFRNC = New String(" ", 25)
.STYPE = New String(" ", 2)
.PRNT = New String(" ", 1)
.AKPRNT = New String(" ", 1)
.STK = New String(" ", 8)
.COCFLG = New String(" ", 3)
.HSTAT = New String(" ", 1)
.SLSREP = New String(" ", 7)
.DRPSHP = New String(" ", 10)
.TAXCDE1 = New String(" ", 7)
.TAXCDE2 = New String(" ", 7)
.TAXCDE3 = New String(" ", 7)
.MCOMP = New String(" ", 3)
.MSITE = New String(" ", 4)
.UDFKEY = New String(" ", 15)
.UDFREF = New String(" ", 25)
.DEXPFLG = New String(" ", 1)
.FILLER = New String(" ", 25)
End With


'Update Sales Order Detail Data Type
With uSODet
.ORDNUM = "220553"
.LINNUM = "06"
.DELNUM = "01"
.STATUS = "3"
.CUSTID = "AJPROD "
.PRTNUM = "50000 "
.TAXABL = "Y"
.GLXREF = "0004010014000 "
.CURDUE = MakeDate(Year(dteToday), Month(dteToday),
Day(dteToday))
.ORGDUE = MakeDate(Year(dteToday), Month(dteToday),
Day(dteToday))
.CUSDUE = MakeDate(Year(dteToday), Month(dteToday),
Day(dteToday))
.SLSUOM = "EA"
.PRICE = 31.0
.ORGQTY = 10
.CURQTY = 10
.DUEQTY = 10
.DISC = 0
.STYPE = "CU"
.PRNT = "N"
.AKPRNT = "N"
.FORCUR = 31.0
.HSTAT = "R"
.TAX1 = 0
End With
Dim rt As Short
Dim prt As IntPtr
'Marshal.StructureToPtr(uSODet, prt, True)
rt = TestStruct(17, uSODet)
MsgBox(rt)
End Sub


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.
 
P

Peter Huang

J

James Radke

Peter,

THAT WORKS!!!! But, I don't understand why I need to define it as
ByValArray - and Public x() as char to define the variables in the
structure? In all the documentation it said to use ByValTStr, and Public x
as string when trying to convert to a char[x]? Can you explain that?

Also, is there a reason you have the VBFixedString attribute at the front of
the field definitions in the structure?

Thanks very much!

Jim

Peter Huang said:
Hi,

According to the C Hearder file, I write a DLL as follows.

[LegacyDLL.dll]
#include "Soedet.h"
SHORT __declspec (dllexport) __stdcall TestStruct(long lSize,SOEDETITEM_PTR
pSDItem)
{
return 0;
}


And I write the Vb.NET declaration as follows which will pass the whole
structure to the C DLL correct on my machine. You may have a try to see if
that works for you.

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure SOEDetItem
<MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=6)> Public ORDNUM() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public LINNUM() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public DELNUM() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public STATUS() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public CUSTID() As Char '
String
<VBFixedString(15), MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=15)> Public PRTNUM() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=6)> Public EDILIN() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public TAXABL() As Char '
String
<VBFixedString(32), MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=32)> Public GLXREF() As Char '
String
Dim CURDUE As Integer ' Btrieve Date
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public FILL01() As Char '
String
Dim ORGDUE As Integer ' Btrieve Date
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public FILL02() As Char '
String
Dim CUSDUE As Integer ' Btrieve Date
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public FILL03() As Char '
String
Dim SHPDTE As Integer ' Btrieve Date
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public FILL04() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public SLSUOM() As Char '
String
<VBFixedString(25), MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=25)> Public REFRNC() As Char '
String
Dim PRICE As Double ' IEEE Float
Dim ORGQTY As Double ' IEEE Float
Dim CURQTY As Double ' IEEE Float
Dim BCKQTY As Double ' IEEE Float
Dim SHPQTY As Double ' IEEE Float
Dim CURSHP As Double ' IEEE Float
Dim DUEQTY As Double ' IEEE Float
Dim INVQTY As Double ' IEEE Float
Dim DISC As Single ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=2)> Public STYPE() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public PRNT() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public AKPRNT() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=8)> Public STK() As Char ' String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=3)> Public COCFLG() As Char '
String
Dim FORCUR As Double ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public HSTAT() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public SLSREP() As Char '
String
Dim COMMIS As Single ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=10)> Public DRPSHP() As Char '
String
Dim QUMQTY As Single ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public TAXCDE1() As Char '
String
Dim TAX1 As Double ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public TAXCDE2() As Char '
String
Dim TAX2 As Double ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=7)> Public TAXCDE3() As Char '
String
Dim TAX3 As Double ' IEEE Float
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=3)> Public MCOMP() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=3)> Public MSITE() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=15)> Public UDFKEY() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=25)> Public UDFREF() As Char '
String
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=1)> Public DEXPFLG() As Char '
String (adChar)
<MarshalAs(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.U1, SizeConst:=24)> Public FILLER() As Char '
String
End Structure
Declare Function TestStruct Lib "LegacyDLL.dll" (ByVal OH As Int32,
ByRef prt As SOEDetItem) As Short

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim uSODet As New SOEDetItem
Dim dteToday As Date
dteToday = Now

'Initialize all the strings to the proper length
With uSODet
.ORDNUM = New String(" ", 6)
.LINNUM = New String(" ", 2)
.DELNUM = New String(" ", 2)
.STATUS = New String(" ", 1)
.CUSTID = New String(" ", 7)
.PRTNUM = New String(" ", 15)
.EDILIN = New String(" ", 6)
.TAXABL = New String(" ", 1)
.GLXREF = New String(" ", 32)
.FILL01 = New String(" ", 2)
.FILL02 = New String(" ", 2)
.FILL03 = New String(" ", 2)
.FILL04 = New String(" ", 2)
.SLSUOM = New String(" ", 2)
.REFRNC = New String(" ", 25)
.STYPE = New String(" ", 2)
.PRNT = New String(" ", 1)
.AKPRNT = New String(" ", 1)
.STK = New String(" ", 8)
.COCFLG = New String(" ", 3)
.HSTAT = New String(" ", 1)
.SLSREP = New String(" ", 7)
.DRPSHP = New String(" ", 10)
.TAXCDE1 = New String(" ", 7)
.TAXCDE2 = New String(" ", 7)
.TAXCDE3 = New String(" ", 7)
.MCOMP = New String(" ", 3)
.MSITE = New String(" ", 4)
.UDFKEY = New String(" ", 15)
.UDFREF = New String(" ", 25)
.DEXPFLG = New String(" ", 1)
.FILLER = New String(" ", 25)
End With


'Update Sales Order Detail Data Type
With uSODet
.ORDNUM = "220553"
.LINNUM = "06"
.DELNUM = "01"
.STATUS = "3"
.CUSTID = "AJPROD "
.PRTNUM = "50000 "
.TAXABL = "Y"
.GLXREF = "0004010014000 "
.CURDUE = MakeDate(Year(dteToday), Month(dteToday),
Day(dteToday))
.ORGDUE = MakeDate(Year(dteToday), Month(dteToday),
Day(dteToday))
.CUSDUE = MakeDate(Year(dteToday), Month(dteToday),
Day(dteToday))
.SLSUOM = "EA"
.PRICE = 31.0
.ORGQTY = 10
.CURQTY = 10
.DUEQTY = 10
.DISC = 0
.STYPE = "CU"
.PRNT = "N"
.AKPRNT = "N"
.FORCUR = 31.0
.HSTAT = "R"
.TAX1 = 0
End With
Dim rt As Short
Dim prt As IntPtr
'Marshal.StructureToPtr(uSODet, prt, True)
rt = TestStruct(17, uSODet)
MsgBox(rt)
End Sub


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.
 
P

Peter Huang

Hi Jim,

#1
This is by design.
If you pass a string from .NET to C++ DLL, then the last value in the
string will be "\0".
e.g.
<VBFixedString(6),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.Unma
nagedType.ByValTStr, SizeConst:=6)> Public ORDNUM28 As String ' String
if you set the ORDNUM28 to "123456", then in the DLL you will get
char[6]="12345"+'\0', that is used to ensure that this is a string.

So usually, when you use the char[] as a string, then you assume the last
char is '\0'. But if you use the char[] as a buffer, then you should pass
the Array from .NET to C++ DLL.

#2
You need to delete the VBFixedString attribute in the declaration, I am
sorry that I didnot clear them when I am testing.


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.
 
P

Peter Huang

Hi Jim,

I am glad that the program works.

Cheers!

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top