Problem calling unmanaged API from C#, works from VB.NET

  • Thread starter Thread starter Ulrika Ziverts
  • Start date Start date
U

Ulrika Ziverts

Hello!
I have a .NET application that communicates with an AS400 application
through PCOM. I call an unmanaged function in the PCOM API to get a
string back representing the screen in the host system. When I call
this function from VB.NET it works fine but from C# I only get a
string containing unreadable characters back. If anyone knows what's
wrong I'd be very happy!

VB.NET code that works:
Private Declare Function hllapi Lib "PCSHLL32.DLL" (ByRef Func As
Integer, ByVal DataString As String, ByRef Length As Integer, ByRef
RetC As Integer) As Integer

Dim testStr As New String(" ", 8000)
ret = hllapi(COPY_PRESENTATION_SPACE, testStr, HllLength,
HllReturnCode)
ResponseBuffer = testStr

testStr is the variable that contains the string I am interested in.

C# code that does not work:
[DllImport("pcshll32.dll",EntryPoint="hllapi",ExactSpelling=false,CharSet=CharSet.Auto,SetLastError=true)]
public static extern int hllapi(ref int Func,
[MarshalAs(UnmanagedType.LPWStr)] string DataString, ref int Length,
ref int RetC);

string hllData = new string(' ', 8000);
int hllLength;
int hllReturnCode;
int ret;
hllLength = 0;
hllReturnCode = 0;
ret = hllapi(ref COPY_PRESENTATION_SPACE, hllData, ref hllLength, ref
hllReturnCode);

responseBuffer = hllData;

hllData either contains nothing or unreadable characters depending on
how I write DllImport. I have tried the following alternatives as
well:

[DllImport("pcshll32.dll",EntryPoint="hllapi",ExactSpelling=false,CharSet=CharSet.Unicode,SetLastError=true)]
public static extern int hllapi(ref int Func,
[MarshalAs(UnmanagedType.LPWStr)] string DataString, ref int Length,
ref int RetC);


[DllImport("pcshll32.dll",EntryPoint="hllapi",ExactSpelling=false,CharSet=CharSet.Unicode,SetLastError=true)]
public static extern int hllapi(ref int Func, string DataString, ref
int Length, ref int RetC);

Regards
Ulrika
 
Ulrika,

Can you give the original C declaration from the header file? I believe
that you should be using an Ansi string, and not a Unicode one, but without
seeing the original declaration, it is impossible to tell.

Also, I believe that the declare keyword in VB will try to default to
using the Ansi version of a function (if it exists) and marshals all string
parameters as ansi strings.

Hope this helps.
 
The declaration in the header file looks like this:

extern long far pascal HLLAPI(WORD*, LPSTR, WORD*, WORD*);

Now I have also tried the following two alternatives and it still works
from VB but not from C#. In the C# case I now get an empty StringBuilder
back and from VB the StringBuilder contains the string I am interested
in.

VB.NET:
Private Declare Function hllapi Lib "PCSHLL32.DLL" (ByRef Func As
Integer, ByVal DataString As StringBuilder, ByRef Length As Integer,
ByRef RetC As Integer) As Integer

Dim sb As New System.Text.StringBuilder(8000)
sb.Append(New String(" ", 8000))
ret = hllapi(COPY_PRESENTATION_SPACE, sb, HllLength, HllReturnCode)

C#:
[DllImport("pcshll32.dll",EntryPoint="hllapi",ExactSpelling=false,CharSe
t=CharSet.Ansi,SetLastError=true)]
private static extern int hllapi(ref int Func, StringBuilder DataString,
ref int Length, ref int RetC);

StringBuilder hllData = new StringBuilder(8000);
hllData.Append(new string(' ', 8000));
int hllLength;
int hllReturnCode;

int ret;
int connectRet;
hllLength = 0;
hllReturnCode = 0;
ret = hllapi(ref COPY_PRESENTATION_SPACE, hllData, ref hllLength, ref
hllReturnCode);
 
Ulrika,

The only difference between the VB.NET code and the C# code once
compiled is that the VB.NET code effectively has ExactSpelling=true,
and you have it set to false in the C# declaration. Does it work if
you change to ExactSpelling=true in the C# code?



Mattias
 
The C# declaration is also using ansi. I don't know what the VB declaration
defaults to if not specified.
 
Back
Top