Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Writing .NET DLL - Problems with string parameters

2 views
Skip to first unread message

Eric Gooden

unread,
Feb 14, 2006, 1:03:38 PM2/14/06
to
I have a DLL written in Delphi 2006 and using .NET code throughout. I am
unable to correctly pass string parameters to this DLL. Things sort of
work, but the strings end up only one character long. For example, the
string 'Happy' ends up as 'H'. I've posted relevant code and results from
my example program (DLL and calling app) below. No matter what type of
string I try to use (or even stringbuilder), I only get the first character
in the TestMe procedure. The integer types work fine.

I don't need to pass values back to the caller - just need them to get to
the DLL correctly. Also, I cannot use the pChar type (or any pointer) as
my code cannot be UNSAFE code. My DLL will be imported into a MS SQL
server (using CLR integration) and so must be 100% .NET and cannot be
unsafe. Is this some sort of Unicode thing where due to how the framework
handles strings it has converted the passed string to where the second byte
is a #0 ?

Any help would be appreciated. Thanks,

Eric Gooden


Code from DLL

procedure TestMe( var sVarString: String; sNormalString: String; out
sOutString: String;
iNormalInteger: Integer; var iVarInteger: Integer; out iOutInteger:
Integer;
sbStringBuilder: StringBuilder);
var sw: StreamWriter;
begin
// Writing results to local text file for debugging
sw:= StreamWriter.Create( 'c:\eric.txt' );

sw.WriteLine( 'sVarString: ' + sVarString );
sw.WriteLine( 'sNormalString: ' + sNormalString );
sw.WriteLine( 'sOutString: ' + sOutString );
sw.WriteLine( 'iNormalInteger: ' + iNormalInteger.ToString );
sw.WriteLine( 'iVarInteger: ' + iVarInteger.ToString );
sw.WriteLine( 'iOutInteger: ' + iOutInteger.ToString );

sw.WriteLine( 'StringBuilder: ' + sbStringBuilder.ToString );

sw.Close;
end;


Code from calling program

// Interface Section
procedure TestMe( var sVarString: String; sNormalString: String; out
sOutString: String;
iNormalInteger: Integer; var iVarInteger: Integer; out iOutInteger:
Integer;
sbStringBuilder: StringBuilder); external 'Library1.dll';

// Implementation Section
.........
procedure Mainf.Button3_Click(sender: System.Object; e: System.EventArgs);
var sTemp1, sTemp2, sTemp3: String;
iTemp1, iTemp2, iTemp3: Integer;
MyArray: array of Char;
sbStringBuilder: StringBuilder;
begin
// Prepare the parms
sTemp1:= '1egooden1';
sTemp2:= '2egooden2';
sTemp3:= '3egooden3';
iTemp1:= 1931;
iTemp2:= 2932;
iTemp3:= 3933;
sbStringBuilder:= StringBuilder.Create;
sbStringBuilder.Capacity:= 128;

sbStringBuilder.Append( 'Eric Gooden was here !' );

// Call the external procedure
TestMe( sTemp1, sTemp2, sTemp3, iTemp1, iTemp2, iTemp3,
sbStringBuilder );
end;
.........


Results are looking like this:

sVarString: 1
sNormalString: 2
sOutString:
iNormalInteger: 1931
iVarInteger: 2932
iOutInteger: 3933
StringBuilder: E

Marc Rohloff [TeamB]

unread,
Feb 14, 2006, 2:39:45 PM2/14/06
to
On Tue, 14 Feb 2006 12:03:38 -0600, Eric Gooden wrote:

> Is this some sort of Unicode thing where due to how the framework
> handles strings it has converted the passed string to where the second byte
> is a #0 ?

It sounds like a good guess. Have you tried to use a DllImport
attribute and specifying the CharSet as Ansi?

--
Marc Rohloff [TeamB]
marc rohloff -at- myrealbox -dot- com

Eric Gooden

unread,
Feb 17, 2006, 5:38:12 PM2/17/06
to
Thanks for your help Marc. Between your comments and the help of my boss
I've made some headway.

What I ended up using is replacing

var sVarString: String

with

[MarshalAs(UnmanagedType.LPWStr)] var sVarString: wideString;

So that the procedure declaration in the DLL looks like this

procedure TestMe([MarshalAs(UnmanagedType.LPWStr)] var sVarString:
wideString; [MarshalAs(UnmanagedType.LPWStr)] var sNormalString: wideString;
[MarshalAs(UnmanagedType.LPWStr)] out sOutString: wideString;


iNormalInteger: Integer; var iVarInteger: Integer; out iOutInteger:
Integer;

sbStringBuilder: StringBuilder); export;

This is allowing me to retrieve the full string. For some reason, it
doesn't work without the VAR in front of the string declaration (I don't
really want to pass the string back to the caller) - but I'll take what I
can get.

I am still working on the StringBuilder and getting that to work.

Eric Gooden


"Marc Rohloff [TeamB]" <"on request"> wrote in message
news:riyj74my4x67$.dlg@marcrohloff.com...

0 new messages