T
Thomas Due
Hi,
I manage an rather old application in which we have some fairly complex (ugly) Delphi code. This is Delphi 6 we're talking about.
Among all this Delphi code there is method for formating a print layout for slip printers. Pass a few parameters to this method and it returns a Delphi string which contains the entire slip, ready for sending to the slip printer.
Now, we're slowly migrating to .NET and am in need of printing this slip from a .NET application. However instead og re-inventing the wheel for generating this slip, we'd like to create a simple DLL in Delphi which is then consumed by the .NET application.
However, this has turned out to pose a few problems.
=====================================================
My first attempt at this:
-------------------------
Delphi method prototype:
------------------------
function GetSlipData(
ARegNo: integer;
APrinterID: integer;
ASlipNo: integer) : string; stdcall;
-------------------------
C# DllImport declaration:
-------------------------
[DllImport("SlipPrint.dll",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPStr)]
internal static extern string GetSlipData(
int regNo,
int printerId,
int slipId);
This results in a
"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Access violation exception.
So, I research and discover that I can't apparently return strings to .NET application through p/invoke, as "strings are immutable". Fair enough, I try using a StringBuilder instead.
=====================================================
My second attempt at this:
-------------------------
Delphi method prototype:
------------------------
function GetSlipData(
AEkspNr: integer;
APrinterID: integer;
ASlipNo: integer;
var output : string) : integer; stdcall;
-------------------------
C# DllImport declaration:
-------------------------
[DllImport("SlipPrint.dll",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
internal static extern int GetSlipData(
int regNo,
int printerId,
int slipId,
[MarshalAs(UnmanagedType.LPStr)]StringBuilder output);
Now I don't get any exceptions, the method returns the correct length of the string, but the StringBuilder only contains five characters.
You see, the string may very well contain null characters, so how on earth do I solve this problem?
How do I pass a string that may contain null characters from a Delphi DLL to a .NET application?
--
Thomas Due
Posted with XanaNews version 1.18.1.6
"If you want a friend in Washington, get a dog."
-- Harry S. Truman
I manage an rather old application in which we have some fairly complex (ugly) Delphi code. This is Delphi 6 we're talking about.
Among all this Delphi code there is method for formating a print layout for slip printers. Pass a few parameters to this method and it returns a Delphi string which contains the entire slip, ready for sending to the slip printer.
Now, we're slowly migrating to .NET and am in need of printing this slip from a .NET application. However instead og re-inventing the wheel for generating this slip, we'd like to create a simple DLL in Delphi which is then consumed by the .NET application.
However, this has turned out to pose a few problems.
=====================================================
My first attempt at this:
-------------------------
Delphi method prototype:
------------------------
function GetSlipData(
ARegNo: integer;
APrinterID: integer;
ASlipNo: integer) : string; stdcall;
-------------------------
C# DllImport declaration:
-------------------------
[DllImport("SlipPrint.dll",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPStr)]
internal static extern string GetSlipData(
int regNo,
int printerId,
int slipId);
This results in a
"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Access violation exception.
So, I research and discover that I can't apparently return strings to .NET application through p/invoke, as "strings are immutable". Fair enough, I try using a StringBuilder instead.
=====================================================
My second attempt at this:
-------------------------
Delphi method prototype:
------------------------
function GetSlipData(
AEkspNr: integer;
APrinterID: integer;
ASlipNo: integer;
var output : string) : integer; stdcall;
-------------------------
C# DllImport declaration:
-------------------------
[DllImport("SlipPrint.dll",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
internal static extern int GetSlipData(
int regNo,
int printerId,
int slipId,
[MarshalAs(UnmanagedType.LPStr)]StringBuilder output);
Now I don't get any exceptions, the method returns the correct length of the string, but the StringBuilder only contains five characters.
You see, the string may very well contain null characters, so how on earth do I solve this problem?
How do I pass a string that may contain null characters from a Delphi DLL to a .NET application?
--
Thomas Due
Posted with XanaNews version 1.18.1.6
"If you want a friend in Washington, get a dog."
-- Harry S. Truman