AccessViolationException when using the qapuiek.dll
-
Hi. I've been trying to convert a function from an olf VBA project into C#. It uses the Quick Address API to check if a postcode as been recoded. I have managed to delcare the references to the API and managed to perform a search but when I try an retrieve the information it gives me an AccessViolationException. My class is.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;namespace PostCodeRecodetest
{
class QAProClass
{
//Declarations//Declare Sub QAInitialise Lib "QAPUIEK.DLL" (ByVal vi1 As Long) \[DllImport("qapuiek.dll")\] public static extern int QAInitialise(long vi1); //Declare Function QAPro\_Open Lib "QAPUIEK.DLL" (ByVal vs1 As String, ByVal vs2 As String) As Long \[DllImport("qapuiek.dll")\] public static extern int QAPro\_Open(string vs1, string vs2); //Declare Sub QAPro\_Close Lib "QAPUIEK.DLL" () \[DllImport("qapuiek.dll")\] public static extern void QAPro\_Close(); //Declare Function QAPro\_Search Lib "QAPUIEK.DLL" (ByVal vs1 As String) As Long \[DllImport("qapuiek.dll")\] public static extern int QAPro\_Search(string vs1); //Declare Function QAPro\_AddrLine Lib "QAPUIEK.DLL" (ByVal vl1 As Long, ByVal vi2 As Long, ByVal vs3 As String, ByVal rs4 As String, ByVal vi5 As Long) As Long \[DllImport("qapuiek.dll")\] public static extern int QAPro\_AddrLine(int vl1, int vi2, string vs3, ref string rs4, int vi5); public string PostCodeRecoded(string postcodeIn) { string rsBuffer = ""; int lOpenReturn = 0; int lSearchReturn = 0; string sSearchString = ""; string returnedPostcode = postcodeIn; string iniPath = "C:\\\\a\_DEV\\\\Qapro.ini"; // Close QA first QAPro\_Close(); // Initialise the dll for faster performance QAInitialise(1); // Open the DLL with the specific ini file. Hard coded for the moment lOpenReturn = QAPro\_Open(iniPath, ""); if (lOpenReturn != 0) return "QAPro Failed"; //Add validation later to insure that the postcode is the correct number of characters sSearchString = postcodeIn; lSearchReturn = QAPro\_Search(sSearchString); if (lSearchReturn == -9811) { lSearchReturn = QAPro\_
-
Hi. I've been trying to convert a function from an olf VBA project into C#. It uses the Quick Address API to check if a postcode as been recoded. I have managed to delcare the references to the API and managed to perform a search but when I try an retrieve the information it gives me an AccessViolationException. My class is.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;namespace PostCodeRecodetest
{
class QAProClass
{
//Declarations//Declare Sub QAInitialise Lib "QAPUIEK.DLL" (ByVal vi1 As Long) \[DllImport("qapuiek.dll")\] public static extern int QAInitialise(long vi1); //Declare Function QAPro\_Open Lib "QAPUIEK.DLL" (ByVal vs1 As String, ByVal vs2 As String) As Long \[DllImport("qapuiek.dll")\] public static extern int QAPro\_Open(string vs1, string vs2); //Declare Sub QAPro\_Close Lib "QAPUIEK.DLL" () \[DllImport("qapuiek.dll")\] public static extern void QAPro\_Close(); //Declare Function QAPro\_Search Lib "QAPUIEK.DLL" (ByVal vs1 As String) As Long \[DllImport("qapuiek.dll")\] public static extern int QAPro\_Search(string vs1); //Declare Function QAPro\_AddrLine Lib "QAPUIEK.DLL" (ByVal vl1 As Long, ByVal vi2 As Long, ByVal vs3 As String, ByVal rs4 As String, ByVal vi5 As Long) As Long \[DllImport("qapuiek.dll")\] public static extern int QAPro\_AddrLine(int vl1, int vi2, string vs3, ref string rs4, int vi5); public string PostCodeRecoded(string postcodeIn) { string rsBuffer = ""; int lOpenReturn = 0; int lSearchReturn = 0; string sSearchString = ""; string returnedPostcode = postcodeIn; string iniPath = "C:\\\\a\_DEV\\\\Qapro.ini"; // Close QA first QAPro\_Close(); // Initialise the dll for faster performance QAInitialise(1); // Open the DLL with the specific ini file. Hard coded for the moment lOpenReturn = QAPro\_Open(iniPath, ""); if (lOpenReturn != 0) return "QAPro Failed"; //Add validation later to insure that the postcode is the correct number of characters sSearchString = postcodeIn; lSearchReturn = QAPro\_Search(sSearchString); if (lSearchReturn == -9811) { lSearchReturn = QAPro\_
Hi, my guess is parameter rs4 is wrong. The VB code (which you included as a comment, very nice) shows "ByVal" however your C# prototype has a "ref" keyword. Now which is it: the content of a string, or a pointer to a string? FWIW: for changeable strings, I tend to pass a StringBuilder (with ample capacity preset), then convert to string afterwards using ToString(). :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
Hi, my guess is parameter rs4 is wrong. The VB code (which you included as a comment, very nice) shows "ByVal" however your C# prototype has a "ref" keyword. Now which is it: the content of a string, or a pointer to a string? FWIW: for changeable strings, I tend to pass a StringBuilder (with ample capacity preset), then convert to string afterwards using ToString(). :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
Thanks for your reply Luc. I've have changed the reference back to a val and know the error does not appear (could have sworn it was earlier!) Now I just get nothing back at all! How would I pass a StringBuilder object to the API when it is asking for a string? Many Thanks
The FoZ
-
Thanks for your reply Luc. I've have changed the reference back to a val and know the error does not appear (could have sworn it was earlier!) Now I just get nothing back at all! How would I pass a StringBuilder object to the API when it is asking for a string? Many Thanks
The FoZ
1. change the C# prototype, from "myFunc(..., string rs4, ...)" to "myFunc(...,StringBuilder rs4,...)". 2. Make sure to create the SB beforehand and give it ample capacity, something like:
StringBuilder sb=new StringBuilder(1000);
myFunc(..., sb, ...);
string rs4=sb.ToString();:)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
1. change the C# prototype, from "myFunc(..., string rs4, ...)" to "myFunc(...,StringBuilder rs4,...)". 2. Make sure to create the SB beforehand and give it ample capacity, something like:
StringBuilder sb=new StringBuilder(1000);
myFunc(..., sb, ...);
string rs4=sb.ToString();:)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
Thanks again Luc One of the things I missed from the VB code is that rsBuffer should be 9 characters in length. Once I changed the to the string builder with a length of 9 I got the correct value returned. 1 function down, 9 to go. Cheers :) :-D
The FoZ
you're welcome. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
Thanks again Luc One of the things I missed from the VB code is that rsBuffer should be 9 characters in length. Once I changed the to the string builder with a length of 9 I got the correct value returned. 1 function down, 9 to go. Cheers :) :-D
The FoZ
TheFoZ wrote:
//Declarations //Declare Sub QAInitialise Lib "QAPUIEK.DLL" (ByVal vi1 As Long) [DllImport("qapuiek.dll")] public static extern int QAInitialise(long vi1);
Change the
long
parameter declaration to anint
. In VBA and VB6 code, the typeLong
is a 32-bti signed integer. In C# and VB.NET, that's anint
,Integer
, orSystem.Int32
.A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008 -
TheFoZ wrote:
//Declarations //Declare Sub QAInitialise Lib "QAPUIEK.DLL" (ByVal vi1 As Long) [DllImport("qapuiek.dll")] public static extern int QAInitialise(long vi1);
Change the
long
parameter declaration to anint
. In VBA and VB6 code, the typeLong
is a 32-bti signed integer. In C# and VB.NET, that's anint
,Integer
, orSystem.Int32
.A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008Right. I missed that one. However, it did survive the long/int mistake, showing the one advantage of little-endianness. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
Right. I missed that one. However, it did survive the long/int mistake, showing the one advantage of little-endianness. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
Lucky, lucky, lucky... OT: Am I the only one who thinks of this[^] when I see "little-endianness"??
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008 -
Lucky, lucky, lucky... OT: Am I the only one who thinks of this[^] when I see "little-endianness"??
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008Dave Kreskowiak wrote:
Am I the only one who thinks...
AFAIK yes you are. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.