Solved

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

Posted on 2014-07-27
10
609 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
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
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
 

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

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

813 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

15 Experts available now in Live!

Get 1:1 Help Now