Solved

What are the VB.NET data type equivalents for a Delphi function?

Posted on 2014-07-27
10
590 Views
Last Modified: 2014-08-20
I need to use a dll developed in Delphi in my VB.NET application.  The Delphi developer has given me the function definition in Delphi:
function GenRegCode(
	RegStr : Widestring; 
	RegOptions, 
	SerialExpireDays,
        RegExpire, 
	RegExpireDays, 
	RegExpireMonths, 
	RegExpireYears : Integer;
        var Serial : Widestring) : LongBool; stdcall;

Open in new window

I'm attempting to call the entry point using the following VB definition:
    <DllImport("C:\Windows\SysWOW64\xxx.dll", EntryPoint:="GenRegCode", SetLastError:=True, _
        CharSet:=CharSet.Auto, ExactSpelling:=True, _
        CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function fGenRegCodeVB( _
        ByVal RegPassword As String, _
        ByVal RegOptions As Long, _
        ByVal SerialExpireDays As Long, _
        ByVal RegExpire As Long, _
        ByVal RegExpireDay As Long, _
        ByVal RegExpireMonth As Long, _
        ByVal RegExpireYear As Long, _
        ByRef Serial As String) As Boolean
    End Function

Open in new window

I'm getting an AccessViolationException error.  The string Serial is set to 1024 spaces -- much longer than the maximum string length that will be returned, which is 24.  Do I have the VB data types defined correctly?  Could this have something to do with a pointer to a string, versus the string itself?
0
Comment
Question by:petekipe
  • 6
  • 2
  • 2
10 Comments
 
LVL 15

Expert Comment

by:Ess Kay
ID: 40223032
delphi data types can be found here
http://www.delphibasics.co.uk/Article.asp?Name=DataTypes
0
 
LVL 15

Expert Comment

by:Ess Kay
ID: 40223034
why don't you treat them all as string and convert them to what you need
0
 

Author Comment

by:petekipe
ID: 40223434
I'm not sure how I would treat all parameters as string in VB.NET and have the dll recognize them correctly...but following your link to Delphi data types, I've made changes to my function definition as follows:
    <DllImport("C:\Windows\SysWOW64\xxx.dll", EntryPoint:="GenRegCodeVB", SetLastError:=True, _
        CharSet:=CharSet.Auto, ExactSpelling:=True, _
        CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function GenRegCodeVB( _
        ByVal RegPassword As String, _
        ByVal RegOptions As Integer, _
        ByVal SerialExpireDays As Integer, _
        ByVal RegExpire As Integer, _
        ByVal RegExpireDay As Integer, _
        ByVal RegExpireMonth As Integer, _
        ByVal RegExpireYear As Integer, _
        ByRef Serial As String) As Boolean
    End Function

Open in new window

Here's the code that calls the function:
    Public Function bGenRegCode() As Boolean
        Dim liDay As Integer
        Dim liMonth As Integer
        Dim liYear As Integer

        Try
            If mbClassInitialized _
            And mbRegisteredNameSet _
            And mbStationNumberSet _
            And mbExpirationDateSet _
            And mbNumberOfMechanicsSet _
            And mbOptionsSet Then

                ' extract day month and year to integers
                liDay = CInt(mdExpirationDate.Day)
                liMonth = CInt(Month(mdExpirationDate))
                liYear = CInt(Year(mdExpirationDate))

                ' build the options integer (7 options in left nibble, # mechanics in right)
                If pfEncodeRegOptions() Then

                    ' make the receiving field big enough for serial number plus null
                    msSerialNumber = Space(32)

                    ' generate the serial number
                    If GenRegCodeVB(msRegisteredName & msStationNumber, _
                                     mshRegOptions, _
                                     0, _
                                     1, _
                                     liDay, _
                                     liMonth, _
                                     liYear, _
                                     msSerialNumber) Then

                        ' successful, clean up serial number and set good return
                        msSerialNumber = Left(msSerialNumber, 24)
                        mbSerialNumberSet = True
                        Return True

                    Else ' negative return from GenRegCode
                        msErrorMessage = msSerialNumber
                        Return False
                    End If

                Else ' negative return from pfEncodeRegOptions
                    Return False
                End If

            Else
                msErrorMessage = "Class not initialized, or required property not set"
                Return False
            End If

        Catch ex As Exception
            With System.Reflection.MethodBase.GetCurrentMethod()
                WriteErrorToLog(ex.ToString, .ReflectedType.Name & "." & .Name)
            End With
            Return False

        End Try
    End Function

Open in new window

I have a break point set on the call (line 26 above). When I step through the call, the program just ends, and I'm not getting any message relative to what went wrong.
0
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 40225640
Please provide more details:
- Q1: Is your Delphi dll compiled as Win32 dll?
- Q2: Which Delphi compiler version? Does it support Unicode?
- Q3: Is your .NET project build as "Any CPU" or x86?
- Q4: What sort of .NET project you have? Win Form/Asp.net/console, etc.?

An educated guess could be that there is a mismatch between .NET and Delphi especially if your >NET project is running in a 64 bit machine and is built as  "Any CPU" or x64. You can easily test it by changing the build to x86 and try again.
0
 

Author Comment

by:petekipe
ID: 40228472
Q1:  (from the Delphi developer) Yes - the original dll is very old
Q2:  (from the Delphi developer) Delphi 7 using Widestrings - compatible with standard .NET strings. (COM compatible BSTR)
Q3:  x86
Q4:  Win Form

The latest appearance of the problem is that the call works without error, however the result I'm getting (in the last parameter, passed ByRef) looks like Chinese:  "ㅃ㔸䌭㕃ⵆ䙃㘶㠭䌹ⴸ䑂〹".  So the two string parameters probably aren't being specified correctly, but I don't know what to do to resolve the problem.

Any ideas would be greatly appreciated!
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:petekipe
ID: 40228476
Oh and one more thing:  The old VB6 project runs perfectly against the dll on the same machine.  It has the numeric parameters typed as Long.
0
 

Author Comment

by:petekipe
ID: 40230783
I think I may have a solution for this:  I've gone back to VB6 and created an ActiveX dll that invokes the Delphi dll.  It seems to be working from VB.NET, although I occasionally get Chinese characters back instead of what I'm expecting...still working on it.
0
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 40251408
Try replacing in VB.NET method with: (I use the same argument names as Delphi version and MarshalAs attribute)
Public Shared Function GenRegCodeVB( _
        ByVal RegStr As String, _
        ByVal RegOptions As Integer, _
        ByVal SerialExpireDays As Integer, _
        ByVal RegExpire As Integer, _
        ByVal RegExpireDays As Integer, _
        ByVal RegExpireMonths As Integer, _
        ByVal RegExpireYears As Integer, _
        <MarshalAs(UnmanagedType.BStr)> ByRef Serial As String) As Boolean
End Function

Open in new window

Notice that <MarshalAs(UnmanagedType.BStr)>  will force .NET to recognize the string as BSTR string and handle memory allocation for you.

If still does not work, please change Serial parameter in  your Delphi code (var Serial : Widestring)  as:
out Serial : Widestring
Note: From your code you are not passing any value(data) back to Delphi, but you are getting the serial string regardless of Serial initial value.
0
 

Accepted Solution

by:
petekipe earned 0 total points
ID: 40264189
Nothing I tried worked, but I finally figured out a way around the problem:  I went back to VB6 and wrote an ActiveX dll that wrapped the Delphi dll.  It's compatible with VB.NET, and all is working fine now.  Thanks to all anyway...
0
 

Author Closing Comment

by:petekipe
ID: 40272096
None of the answers provided solved the problem.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now