473,231 Members | 1,384 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,231 software developers and data experts.

Problems with DllImport and a Delphi native DLL.

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
Jul 4 '07 #1
1 8006
Thomas Due a écrit :
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.
From what I can remember, strings in Pascal (Delphi) are prefixed by
their length, and are allocated (and freed) by specific functions (in
the ShareMem unit).
This conflicts with the definition of strings in .NET, which are null
('\0') terminated, and allocated (and freed) by the .NET environment.

In your case, you want the delphi code to allocate a string, and the
..NET environment (GC) to free it automatically. So you have to choose a
string format that is recognized by both sides : BSTR.

1. Make a wrapper in Delphi for your function that return a BSTR (cf.
http://groups.google.com/group/borla...ff657886892ff).
2. Change your return type attribute to [MarshalAs(UnmanagedType.BStr)]
or [MarshalAs(UnmanagedType.AnsiBStr)] (you will have to determine this
by yourself).

That is all, your original BSTR will be automatically freed by the .NET
environment, calling the proper system API.
>
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.
I am pretty sure you can. The truth is elsewhere...
>
================================================== ===
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?
See my answer above. Had there been no null character in your string,
you would very likely have got an exception as well.

Mathieu
Jul 4 '07 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Morten Rasmusssen | last post by:
Hello When I years ago installed Oracle 7.3 there was a 'native driver' to Borland Delphi 3 (sqlora32.dll and ora73.dll!)! If I today buy and install Oracle 10.0.1, can I then be sure that...
2
by: Leandro H. Delamare | last post by:
Hello group. I'm with a problem a few days with Smart Cards I Have an C++ DLL with some funcions to read a Smart Card. But the problem is, I have the declarations in C++ and a Program Example in...
4
by: erdosa | last post by:
Hi I want use dll (Delphi 7) in c# example delphi procedure GetNev(s:PChar);export; begin
4
by: Islamegy | last post by:
I'm convert a Delphi program to C#.. While i have no knowledge with delphi i must implement everything but for some reason everything working faster on the old program than mine!! i'm working with...
13
by: lukeharpin | last post by:
Hi World, We have been developing Engineering software in Delphi 3,4,5,6,7 for a few years now. This morning we had a discussion about OOP and re-programming the software to which the question...
1
by: Brian Anderson | last post by:
Hello, I have a native, C++ console app that uses ~26MB of RAM when it runs. It uses quite a lot of RAM to make some math but will never xceed 26MB. Now I've made a dll out of this code and...
2
by: Brian Anderson | last post by:
Hello, is it possible to use DllImport to call a DLL in ASP.NET ? Or is it necessarry that my DLL has to be copied into \System32 ? My DLL is a native C++ 7.1 DLL (not managed, no COM, no...
0
by: vidya pawar | last post by:
Hi, I have created a Asp.net Web Application. In this web application I want to use native VC++ dll . I have used "dllImport" atribute. This works fine in Asp.net console Application. While...
3
by: t0x3e8 | last post by:
Hello I load an external library written in Delphi (I don't have any source code of this lib). I do it in this way: public static extern bool userExist(string userName, string password); ...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.