Debug vs Release

G

Guest

Hello,

After getting some posts on forums.microsoft.com but no solution I was asked
to post over here. Hopefully someone here can help with my problem.

I have a Windows Forms application written in C# via VS 2003. It does 100%
of what it should while in Debug mode (running in the debugger as well as
running the .exe from File Explorer.) However, there is one thing it does
not do when compiled in Release mode (running in the debugger nor from the
..exe.) There is an external .dll I have to connect to, to do a screen scrape
of an AS400 application. The linking of it is as follows:

[DllImport("PCSHLL32.dll")] public static extern UInt32 hllapi(out UInt32
Func, StringBuilder sbData, out UInt32 Length, out UInt32 RetC);

Here is the actual code, less the constants, that get run:

public static string ScrapeScreen(string sSessionID, int iPosition, int
iLength, out UInt32 iReturnCode) {
string sScreenText = "";

try {
iReturnCode = Connect(sSessionID);
MessageBox.Show("Connection: " + iReturnCode.ToString());
if(iReturnCode == HARC_SUCCESS) {
iReturnCode = ReadScreen(iPosition, iLength, out sScreenText);
MessageBox.Show("ReadScreen: " + iReturnCode.ToString());
} // if we successfully connected to the session
} catch(Exception e) {
throw(e);
} finally {
iReturnCode = Disconnect(sSessionID);
MessageBox.Show("Disconnect: " + iReturnCode.ToString());
} // try-catch-finally

return sScreenText;
} // ScrapeScreen - Method

public static UInt32 Connect(string sSessionID) {
StringBuilder sbData = new StringBuilder(4);

sbData.Append(sSessionID);
UInt32 rc = 0;
UInt32 iFunction = HA_CONNECT_PS; // function code
UInt32 iLength = 4; // length of data parameter
return hllapi(out iFunction, sbData, out iLength, out rc);
} // Connect - Method

public static UInt32 ReadScreen(int iPosition, int len, out string
sText) {
StringBuilder sbData = new StringBuilder(3000);

UInt32 rc = (UInt32)iPosition;
UInt32 iFunction = HA_COPY_PS_TO_STR;
UInt32 iLength = (UInt32)len;
UInt32 iReturnCode = hllapi(out iFunction, sbData, out iLength, out rc);
sText = sbData.ToString(); // result
return iReturnCode;
} // ReadScreen - Method

public static UInt32 Disconnect(string sSessionID) {
StringBuilder sbData = new StringBuilder(4);
sbData.Append(sSessionID);
UInt32 rc = 0;
UInt32 iFunction = HA_DISCONNECT_PS;
UInt32 iLength = 4;
return hllapi(out iFunction, sbData, out iLength, out rc);
} // Disconnect - Method

When I run in Debug mode it connects and gives me the correct return code of
0 which = Success. However, when I run in Release mode I get a different
return code of 10 which is Unsupported.

There is no code difference between modes. I have no #debug or anything
onther than the exact code. I have even tried swapping the values of
"Enabled Unmanaged Debugging" since the PCSHLL32.dll is most likely writting
in C++ by IBM.

The only thing I can figure is perhaps a security difference between Debug
and Release modes. Is this the case?

Are there any other suggestions on how I can get this piece to work?

Thanks in advance,
Grigs
 
N

Nicholas Paldino [.NET/C# MVP]

Grigs,

Can you show the function signature in the header file for the hllapi
function?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Grigs said:
Hello,

After getting some posts on forums.microsoft.com but no solution I was
asked
to post over here. Hopefully someone here can help with my problem.

I have a Windows Forms application written in C# via VS 2003. It does
100%
of what it should while in Debug mode (running in the debugger as well as
running the .exe from File Explorer.) However, there is one thing it does
not do when compiled in Release mode (running in the debugger nor from the
.exe.) There is an external .dll I have to connect to, to do a screen
scrape
of an AS400 application. The linking of it is as follows:

[DllImport("PCSHLL32.dll")] public static extern UInt32 hllapi(out UInt32
Func, StringBuilder sbData, out UInt32 Length, out UInt32 RetC);

Here is the actual code, less the constants, that get run:

public static string ScrapeScreen(string sSessionID, int iPosition, int
iLength, out UInt32 iReturnCode) {
string sScreenText = "";

try {
iReturnCode = Connect(sSessionID);
MessageBox.Show("Connection: " + iReturnCode.ToString());
if(iReturnCode == HARC_SUCCESS) {
iReturnCode = ReadScreen(iPosition, iLength, out sScreenText);
MessageBox.Show("ReadScreen: " + iReturnCode.ToString());
} // if we successfully connected to the session
} catch(Exception e) {
throw(e);
} finally {
iReturnCode = Disconnect(sSessionID);
MessageBox.Show("Disconnect: " + iReturnCode.ToString());
} // try-catch-finally

return sScreenText;
} // ScrapeScreen - Method

public static UInt32 Connect(string sSessionID) {
StringBuilder sbData = new StringBuilder(4);

sbData.Append(sSessionID);
UInt32 rc = 0;
UInt32 iFunction = HA_CONNECT_PS; // function code
UInt32 iLength = 4; // length of data parameter
return hllapi(out iFunction, sbData, out iLength, out rc);
} // Connect - Method

public static UInt32 ReadScreen(int iPosition, int len, out string
sText) {
StringBuilder sbData = new StringBuilder(3000);

UInt32 rc = (UInt32)iPosition;
UInt32 iFunction = HA_COPY_PS_TO_STR;
UInt32 iLength = (UInt32)len;
UInt32 iReturnCode = hllapi(out iFunction, sbData, out iLength, out
rc);
sText = sbData.ToString(); // result
return iReturnCode;
} // ReadScreen - Method

public static UInt32 Disconnect(string sSessionID) {
StringBuilder sbData = new StringBuilder(4);
sbData.Append(sSessionID);
UInt32 rc = 0;
UInt32 iFunction = HA_DISCONNECT_PS;
UInt32 iLength = 4;
return hllapi(out iFunction, sbData, out iLength, out rc);
} // Disconnect - Method

When I run in Debug mode it connects and gives me the correct return code
of
0 which = Success. However, when I run in Release mode I get a different
return code of 10 which is Unsupported.

There is no code difference between modes. I have no #debug or anything
onther than the exact code. I have even tried swapping the values of
"Enabled Unmanaged Debugging" since the PCSHLL32.dll is most likely
writting
in C++ by IBM.

The only thing I can figure is perhaps a security difference between Debug
and Release modes. Is this the case?

Are there any other suggestions on how I can get this piece to work?

Thanks in advance,
Grigs
 
G

Guest

It was not in the original article that started this adventure but doing some
searching on the internet I believe it is the following IBM C/C++:

#include "hapi_c.h"
int HFunc, HLen, HRc; // Function parameters
char HBuff[1]; // Function parameters
....
HFunc = HA_RESET_SYSTEM; // Run EHLLAPI function
HLen = 0;
HRc = 0;
hllapi(&Func, HBuff, &HLen, &HRc);
if (HRc != 0) {
// ... EHLLAPI access error
}
 
W

Willy Denoyette [MVP]

Grigs said:
Hello,

After getting some posts on forums.microsoft.com but no solution I was asked
to post over here. Hopefully someone here can help with my problem.

I have a Windows Forms application written in C# via VS 2003. It does 100%
of what it should while in Debug mode (running in the debugger as well as
running the .exe from File Explorer.) However, there is one thing it does
not do when compiled in Release mode (running in the debugger nor from the
.exe.) There is an external .dll I have to connect to, to do a screen scrape
of an AS400 application. The linking of it is as follows:

[DllImport("PCSHLL32.dll")] public static extern UInt32 hllapi(out UInt32
Func, StringBuilder sbData, out UInt32 Length, out UInt32 RetC);

Here is the actual code, less the constants, that get run:

public static string ScrapeScreen(string sSessionID, int iPosition, int
iLength, out UInt32 iReturnCode) {
string sScreenText = "";

try {
iReturnCode = Connect(sSessionID);
MessageBox.Show("Connection: " + iReturnCode.ToString());
if(iReturnCode == HARC_SUCCESS) {
iReturnCode = ReadScreen(iPosition, iLength, out sScreenText);
MessageBox.Show("ReadScreen: " + iReturnCode.ToString());
} // if we successfully connected to the session
} catch(Exception e) {
throw(e);
} finally {
iReturnCode = Disconnect(sSessionID);
MessageBox.Show("Disconnect: " + iReturnCode.ToString());
} // try-catch-finally

return sScreenText;
} // ScrapeScreen - Method

public static UInt32 Connect(string sSessionID) {
StringBuilder sbData = new StringBuilder(4);

sbData.Append(sSessionID);
UInt32 rc = 0;
UInt32 iFunction = HA_CONNECT_PS; // function code
UInt32 iLength = 4; // length of data parameter
return hllapi(out iFunction, sbData, out iLength, out rc);
} // Connect - Method

public static UInt32 ReadScreen(int iPosition, int len, out string
sText) {
StringBuilder sbData = new StringBuilder(3000);

UInt32 rc = (UInt32)iPosition;
UInt32 iFunction = HA_COPY_PS_TO_STR;
UInt32 iLength = (UInt32)len;
UInt32 iReturnCode = hllapi(out iFunction, sbData, out iLength, out rc);
sText = sbData.ToString(); // result
return iReturnCode;
} // ReadScreen - Method

public static UInt32 Disconnect(string sSessionID) {
StringBuilder sbData = new StringBuilder(4);
sbData.Append(sSessionID);
UInt32 rc = 0;
UInt32 iFunction = HA_DISCONNECT_PS;
UInt32 iLength = 4;
return hllapi(out iFunction, sbData, out iLength, out rc);
} // Disconnect - Method

When I run in Debug mode it connects and gives me the correct return code of
0 which = Success. However, when I run in Release mode I get a different
return code of 10 which is Unsupported.

There is no code difference between modes. I have no #debug or anything
onther than the exact code. I have even tried swapping the values of
"Enabled Unmanaged Debugging" since the PCSHLL32.dll is most likely writting
in C++ by IBM.

The only thing I can figure is perhaps a security difference between Debug
and Release modes. Is this the case?

Are there any other suggestions on how I can get this piece to work?

Thanks in advance,
Grigs



I can hardly believe your hllapi signature is correct, although I can't directly explain why
it works in release mode.


Consider the part of the code that performs the Connect...

UInt32 rc = 0;
UInt32 iFunction = HA_CONNECT_PS; // function code
UInt32 iLength = 4; // length of data parameter
return hllapi(out iFunction, sbData, out iLength, out rc);
} // Connect - Method

Here you pass a 'Function' code (HA_CONNECT_PS) as 'out' parameter, IMO this shouldn't be an
out parameter. The same goes for the third parameter, here you pass the length of the Data
parameter to the callee, this shouldn't be passed as out.
Another thing you should check, is the data parameter, are you sure you need to pass a
StringBuilder? I guess it's not, I suspect the API expects a void*.
Also, you pass an hard coded value, here you have to make sure in your DllImport declaration
that the data is passed ansi character encoded.

Anyway if you need more help, you will have to post the C API declaration.

Willy.
 
N

Nicholas Paldino [.NET/C# MVP]

Grigs,

Can you include the COMPLETE function signature, with parameter names
and types in the correct order, as well as return type.

From what I can see here though, your signature that you use for
P/Invoke in .NET is completely wrong. Based on just this, it should be:

[DllImport("PCSHLL32.dll")]
public static extern UInt32 hllapi(int HFunc, int HLen, int HRC, byte
HBuff);

However, I don't think this is right, because what you displayed is not
what would be in the header file.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Grigs said:
It was not in the original article that started this adventure but doing
some
searching on the internet I believe it is the following IBM C/C++:

#include "hapi_c.h"
int HFunc, HLen, HRc; // Function parameters
char HBuff[1]; // Function parameters
...
HFunc = HA_RESET_SYSTEM; // Run EHLLAPI function
HLen = 0;
HRc = 0;
hllapi(&Func, HBuff, &HLen, &HRc);
if (HRc != 0) {
// ... EHLLAPI access error
}
 
W

Willy Denoyette [MVP]

Grigs said:
It was not in the original article that started this adventure but doing some
searching on the internet I believe it is the following IBM C/C++:

#include "hapi_c.h"
int HFunc, HLen, HRc; // Function parameters
char HBuff[1]; // Function parameters
...
HFunc = HA_RESET_SYSTEM; // Run EHLLAPI function
HLen = 0;
HRc = 0;
hllapi(&Func, HBuff, &HLen, &HRc);
if (HRc != 0) {
// ... EHLLAPI access error
}


Nicholas Paldino said:
Grigs,

Can you show the function signature in the header file for the hllapi
function?


O, the tool a look in the HLLAPI programmers guide, and here is what I discovered..

[DllImport("PCSHLL32.dll")] public static extern UInt32 hllapi(ref UInt32
Func, StringBuilder sbData, out UInt32 Length, out UInt32 RetC);

In case of a "connect" call you only need to specify the 'function' and 'sessionId', like
this:

UInt32 rc = 0;
UInt32 iFunction = HA_CONNECT_PS; // function code
return hllapi(out iFunction, sbData, out iLength, out rc);
} // Connect - Method

Note that you should inspect the 'rc' value on return, the return value of the API is of
little value.

Willy.
 
W

Willy Denoyette [MVP]

Willy Denoyette said:
Grigs said:
It was not in the original article that started this adventure but doing some
searching on the internet I believe it is the following IBM C/C++:

#include "hapi_c.h"
int HFunc, HLen, HRc; // Function parameters
char HBuff[1]; // Function parameters
...
HFunc = HA_RESET_SYSTEM; // Run EHLLAPI function
HLen = 0;
HRc = 0;
hllapi(&Func, HBuff, &HLen, &HRc);
if (HRc != 0) {
// ... EHLLAPI access error
}


Nicholas Paldino said:
Grigs,

Can you show the function signature in the header file for the hllapi
function?


O, the tool a look in the HLLAPI programmers guide, and here is what I discovered..

[DllImport("PCSHLL32.dll")] public static extern UInt32 hllapi(ref UInt32
Func, StringBuilder sbData, out UInt32 Length, out UInt32 RetC);

In case of a "connect" call you only need to specify the 'function' and 'sessionId', like
this:

UInt32 rc = 0;
UInt32 iFunction = HA_CONNECT_PS; // function code
return hllapi(out iFunction, sbData, out iLength, out rc);
} // Connect - Method

Note that you should inspect the 'rc' value on return, the return value of the API is of
little value.

Willy.


Bluetooth keyboard interferences...
O, the tool a look in the HLLAPI ...
should read:
Ok, I took a look in the HLLAPI ...

Willy.
 
G

Guest

I agree about the signature. I got the initial class from an article on
CodeProject xxx.

I wound up attempting to make some changes to the definition and at its
current state it looks like this:

[DllImport("PCSHLL32.dll")]
public static extern int hllapi(out int Func, StringBuilder sbData, out
int Length, out int RetC);

I did try and make the Function not an out as well as the length. I tried
one and then the other. I always got errors and not even the connection
worked. I then tried to make the StringBuilder a string, a byte[] and a
char[] with no luck each time.

I guess I will pass this along to the C API feed.
 

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